聊聊 Promise

作者: jaymz明 | 来源:发表于2020-03-05 16:54 被阅读0次

    Promise相信写前端的同学都不陌生,本意是承诺,答应完成某事。promise主要用于异步计算。可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。还可以在对象之间传递和操作promise,帮助我们处理队列。
    和其他异步调用的优点在于:

    1. promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)。
    2. 并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据。
    3. 代码风格,容易理解,便于维护。
    4. 多个异步等待合并便于解决。
      promise有三个状态:
      1、pending[待定]初始状态
      2、fulfilled[实现]操作成功
      3、rejected[被否决]操作失败

    当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
    promise状态一经改变,不会再变。
    Promise对象的状态改变,只有两种可能:

    • 从pending变为fulfilled
    • 从pending变为rejected。

    这两种情况只要发生,状态就凝固了,不会再变了。
    所以我们可以生成这样的链式调用 new Promise().then().then().catch()
    我们来看下Promise可以怎么处理异常:
    第一种catch+then

    //catch+then
    new Promise(resolve => {
          throw new Error('this is a error')
      }).catch(err=>{
          console.error('catch+then: I catch',err)
      }).then(res=>{
          console.log('222')
      }).catch(err=>{
          console.error('catch+then: I catch2',err)
      })
    
    image.png

    可以看出catch返回的Promise的状态也是resolved,可以继续执行then。
    第二种 then

      //then
      new Promise(()=>{
          console.log('start...')
          throw new Error('this is a error')
    
      }).catch(err=>{
          console.error('i catch:', err)
        throw new Error('this is another error')
      }).then(()=>{
          console.log('test')
      }).then(()=>{
          console.log('test2')
      }).catch(err=>{
          console.error('I also catch ',err)
      })
    
    image.png

    可以看出抛出错误变为rejected状态,所以绕过两个then直接跑到最下面的catch。
    Promise.all(p1,p2...),等待p1,p2 都完成了返回。
    Promise.race(p1,p2,..),只要有一个完成,就返回。
    可用于异步操作和定时器放在一起,如果定时器先触发,就认为超时,告知用户;
    接下来,我们来挑战下Promise经典的四道题:

    1. doSomething().then(function () {
      return doSomethingElse();
    });
    2. doSomething().then(function () {
      doSomethingElse();
    }).then(final);
    3. doSomething().then(doSomethingElse()).then(final);
    4. doSomething().then(doSomethingElse);
    

    第一个:先执行doSomething(),然后再执行doSomethingElse(),然后再往下执行。
    第二个:没有return,所以函数体中不返回新的promise实例,所以是两个队列,在doSomething执行完后,final和doSomethingElse同时执行。
    第三个:函数体中是doSomethingElse(),是一个可执行的promise实例,可以和doSomething一起执行,然后它的结束状态不管,final函数会在doSomething结束后执行。
    第四个:跟平时见到的一样,resolve和reject,按顺序执行。
    综上,Promise感觉和java中的builder构造器一样,又有点像适配器模式那样,将复杂的请求分而治之,无疑是前端开发的一大利器。

    相关文章

      网友评论

        本文标题:聊聊 Promise

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