promise

2018-04-21  本文已影响0人  钱学敏

promise 异步编程的解决方案

这篇文章写的比较好 http://blog.csdn.net/u011500781/article/details/53055856
bluebird - 封装了 ES6 原生 Promise

jquery 1.5之后有了jQuery Deferred 是对promise规范的实现
复杂的AJAX嵌套可以改成如下形式

var promise1 = $.ajax(url1);  
var promise2 = promise1.then(function(data){  
    return $.ajax(url2, { "data": data });  
});  
var promise3 = promise2.then(function(data){  
    return $.ajax(url3, { "data": data });  
});  
promise3.done(function(data){  
    // data retrieved from url3  
});  

如下是我自己的一点理解

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    body {
        background: black
    }

    img {
        border-radius: 50%;
        -webkit-animation: rotate 3s linear 0s infinite alternate;
        -o-animation: rotate 3s linear 0s infinite alternate;
        animation: rotate 3s linear 0s infinite alternate;
    }

    @keyframes rotate {
        from {
            transform: rotate(0deg);
        }
        to {
            transform: rotate(360deg);
        }
    }

    .eye {
        width: 20px;
        height: 20px;
        background-color: rgba(255, 255, 255, 0.8);
        border-radius: 50%;
        box-shadow: 30px 0px 0px 0px rgba(255, 255, 255, 0.8);
        position: relative;
        margin: 36px 26px;
    }

    .eye:after {
        background-color: #59488b;
        width: 10px;
        height: 10px;
        box-shadow: 30px 0px 0px 0px #59488b;
        border-radius: 50%;
        left: 9px;
        top: 8px;
        position: absolute;
        content: "";
        -webkit-animation: eyeball 2s linear infinite alternate;
        -moz-animation: eyeball 2s linear infinite alternate;
        animation: eyeball 2s linear infinite alternate;
    }

    @-webkit-keyframes eyeball {
        0% {
            left: 9px;
        }
        100% {
            left: 1px;
        }
    }

    @-moz-keyframes eyeball {
        0% {
            left: 9px;
        }
        100% {
            left: 1px;
        }
    }

    @keyframes eyeball {
        0% {
            left: 9px;
        }
        100% {
            left: 1px;
        }
    }
    </style>
</head>

<body>
    <div class="eye"></div>
    <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524239827291&di=1ea316d9e0c45ed800220dfebdacb760&imgtype=0&src=http%3A%2F%2Fimg.lanqb.com%2F20160605%2F1465092344VOdLCUAW-f.jpg" width="200px" alt="">
    <script>
    // 一个promise代表一个异步操作的最终执行结果。让异步操作变得易于维护 职责单一
    // 1模拟ajax 普通写法
    {
        //块级作用域
        let ajax = function(callback) {
            console.log('start 1');
            setTimeout(function() {
                callback && callback.call()
            }, 1000)
        }

        ajax(function() {
            console.log('get data success1')
        })
    }

    // 2promise 方式
    // 执行一个异步任务如下面的 ajax,会返回一个结果,这个结果是个promise ,它保证他将会变成一个成功或者失败

    {
        let ajax = function() {
            console.log('start 2');
            return new Promise(function(resolve, reject) {
                //做一些异步操作
                setTimeout(function() {
                    resolve()
                }, 1000)
            })
        }

        ajax().then(function() {
            console.log('get data success2')
        })
    }

    // 3串联操作
    {
        let ajax = function() {
            console.log('start 3');
            return new Promise(function(resolve, reject) {
                //做一些异步操作
                setTimeout(function() {
                    resolve()
                }, 1000)
            })
        }

        ajax()
            .then(function() {
                console.log('get data success2')
                return new Promise(function(resolve, reject) {
                    //做一些异步操作
                    setTimeout(function() {
                        resolve()
                    }, 1000)
                })
            })
            .then(function() {
                console.log('get data success3')
            })
    }

    // 4异常捕获.  可以捕获语法错误以及业务逻辑错误 Error和reject
    {
        let ajax = function(num) {
            console.log('start 4');
            return new Promise(function(resolve, reject) {
                //做一些异步操作
                //throw new Error('-----------wrong')  
                //         setTimeout(function() {
                if (num > 5) {
                    resolve()
                } else {
                    reject('失败走这里')
                }
                //      }, 1000)
            })
        }

        ajax(6).then(function() {
            console.log('get data success4')
        }).catch(function(err) {
            console.log('---catch', err)
        })

        ajax(3).then(function() {
            console.log('get data success5')
        }).catch(function(err) {
            console.log('---catch', err)
        })
    }

    //5 Promise.all 应用场景 所有图片加载完再添加到页面 优化用户体验
    {
        let loadImg = function(src) {
            return promise = new Promise(function(resolve, reject) {
                let img = document.createElement('img');
                img.src = src;
                img.onload = function() {
                    resolve(img) //异步成功执行resolve
                }
                img.onerror = function() {
                    reject(img) //异步失败执行reject
                }

            })
        }

        // 添加所有图片到页面
        let addImagesToBody = function(imgs) {
            imgs.forEach(function(img) {
                document.body.appendChild(img)
            })
        }

        //Promise.all 返回一个新的promise ,当数组中所有promise实例的状态发生改变之后 新的promise实例状态才发生变化
        Promise.all([
            loadImg('http://iconfont.alicdn.com/t/1494395652678.png@200h_200w.jpg'),
            loadImg('http://iconfont.alicdn.com/t/1508911280546.jpg@200h_200w.jpg'),
            loadImg('http://iconfont.alicdn.com/t/1493708103743.jpeg@200h_200w.jpg')
        ]).then(addImagesToBody)

    }

    //6  Promise.race应用场景 几张图中只要有一个加载完,就显示在页面中 
    {
        let loadImg = function(src) {
            return promise = new Promise(function(resolve, reject) {
                let img = document.createElement('img');
                img.src = src;
                img.onload = function() {
                    resolve(img) //异步成功执行resolve
                }
                img.onerror = function() {
                    reject(img) //异步失败执行reject
                }

            })
        }

        // 添加所有图片到页面
        let addImagesToBody = function(img) {
            document.body.appendChild(img)
        }

        //Promise.race 返回一个新的promise ,当数组中所有promise实例中只要有一个的状态发生改变 新的promise实例状态就发生变化
        Promise.race([
            loadImg('http://iconfont.alicdn.com/t/1494395652678.png@200h_200w.jpg'),
            loadImg('http://iconfont.alicdn.com/t/1508911280546.jpg@200h_200w.jpg'),
            loadImg('http://iconfont.alicdn.com/t/1493708103743.jpeg@200h_200w.jpg')
        ]).then(addImagesToBody)

    }

    //7  async await ,
    // async表示是一个async函数
    //await只能用在这个函数里
    //await后面跟着的应该是一个promise对象
    //async await是generator函数的语法糖,解决了异步嵌套黑洞的写法问题 真正解决异步问题的是promise
    {
        async function aa() {
            let p1 = function() {
                return new Promise(function(resolve, reject) {
                    setTimeout(function() {
                        resolve('p1')
                    }, 1000)
                })
            }
            let a1 = await p1(); //a1表示promise返回的结果
            console.log('await---' + a1)
        }
        aa()

    }
    </script>
</body>

</html>
上一篇下一篇

猜你喜欢

热点阅读