写在前面:

在学习微信小程序过程中了解到利用Promise,可以对事件请求的回调进行优化,避免了多重回调造成的"回调地狱"问题,本文主要用作介绍及记录在使用Promise过程中遇到的问题和思考。

什么是Promise?

Promise 是一个对象,相当于一个容器,里面存的是一个异步操作的结果,并且代表一个未来可能会完成的操作。

Promise的三种状态:

  • pending:代表操作进行
  • resolved:代表操作成功
  • rejected:代表操作失败

Promise的两种状态改变的方式:

  • 当异步操作成功时,从pending转变为resolved,

  • 当异步操作失败时,从pending转变为rejected。

PS.一旦状态改变,就会一直保持这个状态,不会再发生变化。当状态发生变化,promise.then绑定的函数就会被调用。

Promise一旦新建就会「立即执行」(它属于microtask),无法取消。这也是它的缺点之一。

Promise的好处:

  • 在“回调地狱”问题中,最显而易见的困扰就是阅读困难,下一个操作需要上一个操作的结果导致异步操作的多重嵌套,引用廖雪峰的一句总结:

廖雪峰对Promise的总结

  • 多个异步任务是为了容错去访问用同一资源时, 可以使用Promise.race([promise实例...])
  • 多个异步任务并行执行时,比如ajax访问两个接口, 可以用Promise.all([promise实例...])

使用Promise的约定:

  • 在本轮事件循环完成之前,回调函数是不会被调用。
  • 通过then()添加的回调函数一定会被调用,即使它是在异步操作完成之后才被添加的函数
  • 可以多次调用多个then()函数,它们会按照插入顺序一个个独立执行

Promise的作用:

  • 处理异步任务
  • 保存异步结果状态
  • 异步代码同步化

Promise的使用:

套路一般为:

  1. 定义一个函数, 函数内部使用new Promise()的方式来返回一个promise对象,resolve用来保存异步处理成功的结果,reject用来保存异常处理的结果。

  2. 然后函数调用,传参。

  3. 用then方法处理链式调用, then中的回调用来处理异步结果。

  4. 用catch方法处理错误情况,,也可以用then(null, function() {})代替catch。

  5. then的回调中也可return一个值,会被包装成一个新的promise对象, 以此可以继续调用then方法。

  6. 处理同步任务

    new Promise((resolve,reject)=>{
            resolve(1);
        })
    .then(res=>{
        console.log(res);
    });
    复制代码

    输出结果:

    1
    Ps.当状态发生变化后执行then方法,并将resolve或reject的结果作为then方法接受回调函数的参数
    复制代码
  7. 处理异步任务

    new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve("成功");
            },1000);
        })
    .then(res=>{
        console.log(res);
    });
    复制代码

    输出结果:

    成功
    Ps.当异步代码执行成功时,会调用resolve(...), 当异步代码失败时就会调用reject(...)
    复制代码
  8. 处理链式调用

    new Promise((resolve, reject) => {
        console.log('初始化');
        resolve();
    })
    .then(() => {
        throw new Error('有哪里不对了');
        console.log('执行「这个」”');
    })
    .catch(() => {
        console.log('执行「那个」');
    })
    .then(() => {
        console.log('执行「这个」,无论前面发生了什么');
    });
    复制代码

    输出结果:

    初始化
    执行“那个”
    执行“这个”,无论前面发生了什么
    Ps.因为抛出了错误‘有哪里不对了’,所以前一个‘执行「这个」’没有被输出
    复制代码

参考:

[1].MDN web docs-developer.mozilla.org/zh-CN/docs/…

[2].AustinNorman:Promise的学习总结-www.ctolib.com/topics-1388…

[3].cz160:利用ES6进行Promise封装总结-segmentfault.com/a/119000001…

[4].砖用西瓜:Promise到底解决了什么问题-segmentfault.com/a/119000001…