美文网首页
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