美文网首页
ES6之Promise详解

ES6之Promise详解

作者: 我爱阿桑 | 来源:发表于2020-06-06 15:52 被阅读0次
    1. 什么是promise?
    • promise是es6新增的异步编程解决方案,在代码中表现为一个对象。

    需求:从网络上加载3个资源, 要求加载完资源1才能加载资源2, 加载完资源2才能加载资源3, 前面任何一个资源加载失败, 后续资源都不加载
    从前都这样做

     function request(fn) {
            setTimeout(function () {
                fn("拿到的数据");
            }, 1000);
        }
        request(function (data) {
            console.log(data, 1);
            request(function (data) {
                console.log(data, 2);
                request(function (data) {
                    console.log(data, 3);
                });
            });
        });
    

    2. 接下来promise闪亮登场!!!

    promise就是为了避免层层回调,将异步操作可以变为同步流程来显示的。

      function request() {
            return new Promise(function (resolve, reject) {
                setTimeout(function () {
                    resolve("拿到的数据");
                }, 1000);
            });
        }
        request().then(function (data) {
            console.log(data, 1);
            return request();
          }).then(function (data) {
            console.log(data, 2);
            return request();
         }).then(function (data) {
            console.log(data, 3);
         });
    

    3. 如何创建promise呢?

    new Promise(function(resolve, reject){});就创建完毕了。
    记住,promise不是异步的,只要创建了promise对象就会立即执行存放的代码。


    4. promise如何通过同步流程来表示异步的操作的呢?

    promise对象是通过状态的改变来实现的,只要状态改变就会自动触发对应的函数。


    5. promise的三种状态
    • pending:默认状态,只要没有告诉promise是成功还是失败。就是pending状态。
    • resolved:只要调用resolve函数,状态就会变为fulfilled,表示操作成功。
    • rejected:只要调用rejected函数,状态就会变为rejected,表示操作失败。
    • 状态一经改变,既不可逆。

    6. 监听promise状态变化

    resolved --->then()
    rejected --->catch()


    7. then()方法
    • then()接受两个参数:
    • 第一个参数是状态切换为成功时的回调
    • 第二个参数是状态切换为失败时的回调
     promise.then(function () {
            console.log("成功");
        }, function () {
            console.log("失败");
        });
    
    • then方法每次执行完毕后会返回一个新的promise对象
    • 可以通过上一个promise对象的then方法给下一个promise对象的then方法传递参数
      注意点:
      无论是在上一个promise对象成功的回调还是失败的回调传递的参数,都会传递给下一个promise对象成功的回调
          let promise = new Promise(function (resolve, reject) {
           // resolve("111"); // 将状态修改为成功
           reject("aaa"); // 将状态修改为失败
         });
          let p2 = promise.then(function (data) {
           console.log("成功1", data);
           return "222";
          }, function (data) {
             console.log("失败1", data);
             return "bbb";
         });
           p2.then(function (data) {
             console.log("成功2", data);
            }, function (data) {
             console.log("失败2", data);
         });
    

    上述打印结果就是 :失败1 aaa , 成功2 bbb

    • 如果then方法返回的是一个promise对象,那么将会返回promise对象的执行结果中的值传递给下一个then()方法
    let promise = new Promise(function (resolve, reject) {
            resolve("111"); // 将状态修改为成功
            // reject("aaa"); // 将状态修改为失败
        });
        let ppp = new Promise(function (resolve, reject) {
            // resolve("222"); // 将状态修改为成功
            reject("bbb"); // 将状态修改为失败
        });
        let p2 = promise.then(function (data) {
            console.log("成功1", data);
            return ppp;
        }, function (data) {
            console.log("失败1", data);
            return "bbb";
        });
        p2.then(function (data) {
            console.log("成功2", data);
        }, function (data) {
            console.log("失败2", data);
        });
    

    上述打印结果就是 :成功1 111 , 失败2 bbb

    • 同一个promise对象可以多次调用then方法, 当该promise对象的状态为成功时所有then方法都会被执行
    let promise = new Promise(function (resolve, reject) {
            // resolve(); // 将状态修改为成功
            reject(); // 将状态修改为失败
        });
        promise.then(function () {
            console.log("成功1");
        }, function () {
            console.log("失败1");
        });
        promise.then(function () {
            console.log("成功2");
        }, function () {
            console.log("失败2");
        });
    打印结果是成功1  成功2
    
    8. catch()方法
    • catch 其实是 then(undefined, () => {}) 的语法糖
     let promise = new Promise(function (resolve, reject) {
            // resolve(); // 将状态修改为成功
            reject(); // 将状态修改为失败
        });
        promise.catch(function () {
            console.log("abc");
        });
    
    • 注意点: 如果需要分开监听, 也就是通过then监听成功通过catch监听失败
      那么必须使用链式编程, 否则会报错
    • 和then方法一样,可以传递参数给catch方法中的回调函数。
    let promise = new Promise(function (){
       reject('123')
    })
    promise.catch(function(data){
        console.log(data)
    })
    
    • 和then方法一样,同一个promise方法可以多次调用catch方法。如下:当该promise对象的的状态为rejected时,所有的catch都会执行。
    let promise = new Promise(function (resolve, reject) {
            reject();
        });
        promise.catch(function () {
            console.log("失败1");
        });
        promise.catch(function () {
            console.log("失败2");
        });
        promise.catch(function () {
            console.log("失败3");
        });
      
    
    • 和then一样, catch方法每次执行完毕后会返回一个新的promise对象
    • 和then方法一样, 上一个promise对象也可以给下一个promise成功的传递参数
    • 注意点:
      无论是在上一个promise对象成功的回调还是失败的回调传递的参数,都会传递给下一个promise对象成功的回调
    • 和then一样, catch方法如果返回的是一个Promise对象, 那么会将返回的Promise对象的 执行结果中的值传递给下一个catch方法
    • 和then方法第二个参数的区别在于, catch方法可以捕获上一个promise对象then方法中的异常
    9. all()方法
    • all方法接收一个数组
    • 如果数组中有多个promise对象,只有的都成功了,才会执行then()方法,并且会按照添加的顺序,将所有成功的结果都打包的一个数组中返回给我们
    • 如果数组中不是promise对象,那么会直接执行.then()方法
     let arr = [
            "http://www.it666.com/files/system/block_picture_1555415767.png",
            "http://www.it666.com/files/system/block_picture_1555422597.jpg",
            "http://www.it666.com/files/system/block_picture_1555419713.jpg"
        ];
        function loadImage(url) {
            return new Promise(function (resolve, reject) {
                let oImg = new Image();
                let time = Math.random() * 1000;
                // console.log(time);
                setTimeout(function () {
                    oImg.src = url;
                }, time);
                // oImg.src = url;
                oImg.onload = function () {
                    resolve(oImg);
                }
                oImg.onerror = function () {
                    reject("图片加载失败了");
                }
            });
        }
      Promise.all([loadImage(arr[0]), loadImage(arr[1]),loadImage(arr[2])])
            .then(function (result) {
                // console.log(result);
                result.forEach(function (oImg) {
                    document.body.appendChild(oImg);
                });
            })
            .catch(function (e) {
                console.log(e);
            });
    
    结果是: 1591432874(1).jpg

    相关文章

      网友评论

          本文标题:ES6之Promise详解

          本文链接:https://www.haomeiwen.com/subject/ftextktx.html