聊聊 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