深入理解promise

promise规范

规范-promise/A+ 术语

1.promise 一个有then方法的对象或函数,行为符合本规范
2.thenable 一个定义了then方法的对象和函数
3.值,value 任何JavaScript的合法值
4.异常,exception throw语句抛出的值
5.拒绝原因,reason 一个标示promise被拒绝原因的值

规范-promise/A+ 要求

promise的状态:

  • pending
  • fulfilled
  • rejected
    state:pending --- value --->state:fulfilled
    |-- reason--->state:rejected

then方法

const promise2 = promise1.then(onFulfilled,onRejected);

then方法的参数
  • 两个函数参数
  • onFulfilled在promise完成后被调用,onRejected在promise被拒绝执行后调用
  • 只被调用一次
    then方法的调用:可以调用多次
    then方法的返回值:promise
  1. onFulfilled不是函数,promise1的状态是fulfilled----state:fulfilled,value:同promise1
  2. onRejected不是函数,promise1的状态是rejected----state:rejected,reason:同promise1
  3. onFulfilled或者onRejected return x----进入解析过程

promise解析过程

  • 抽象模型resolve(promise,x)
  • 如果promise和x指向相同的值
  • 如果x是一个promise
  • 如果x是一个对象或一个函数
  • 如果x不是对象也不是函数
function resolve(promise,x){
  if(x === promise){
    return reject(promise,new TypeError('cant be the same'));
  }
  if(isPromise(x)){
    if(x.state === 'pending'){
      return x.then(() => {
        resolve(promise,x.value);
      },() => {
        reject(promise,x.value);
      })
    }
    if(x.state == 'fulfilled'){
      return fulfill(promise,x.value);
    }
    if(x.state === 'rejected'){
      return reject(promise,x.value)
    }
  }else if(isObject(x) || isFunction(x)){
    let then;
    try{
      then = x.then;
    }catch(e){
      return reject(promise,e);
    }
    if(isFunction(then)){
      let isCalled = false;
      try{
        then.call(x,function resolvePromise(y){
          if(isCalled){
            return;
          }
          isCalled = true;
          resolve(promise,y);
        },function rejectPromise(r){
          if(isCalled){
            return;
          }
          isCalled = true;
          reject(promise,r)
        });
      }catch(e){
        if(!ifCalled){
          return reject(promise,e);
        }
      }
    }else{
      return fulfill(promise,x)
    }
  }else{
    return fulfill(promise,x)
  }
}

ES6 promise API

Promise构造函数

构造函数

new Promise(function(resolve,reject){
  //rosolve(value)
  //reject(reason)
})

说明

  • 函数作为参数
  • resolve函数将promise状态从pending变成resolved(fulfilled)
  • reject函数将promise状态从pending变成rejected

静态方法

  • Promise.resolve(param) : 等同于 new Promise(function(resolve,reject){resolve(param)})
  • Promise.reject(param) : 等同于 new Promise(function(resolve,reject){reject(param)})
  • Promise.all([p1,...,pn) : 输入一组promise返回一个新的promise,全部promise都是fulfilled结果才是fulfilled状态
  • Promise.allSettled([p1,...,pn) : 输入一组promise返回一个新的promise,全部promise状态改变后结果promise变成fulfilled状态
  • Promise.race([p1,...,pn) : 输入一组promise返回一个新的promise,结果promise的状态跟随第一个变化的promise状态

实例方法

  • promise.then(onFulfilled,onRejected) : promise状态改变之后的回调,返回新的promise对象
  • promise.catch(function(reason){}) : t同promise.then(null,onRejected),promise状态改为rejected的回调
  • promise.finally(function(reason){//test} : 同promise.then(function(){//test},function(){//test}),不管promise状态如何都会执行

注意点

  • then、catch返回的promise是新的promise,不是原来的promise.
  • Promise对象的错误会“冒泡”,直到被捕获为止,错误会被下一个catch语句捕获。

Promise实践

  • 不要忘记catch捕捉错误
  • then方法中使用return
  • 传递函数给then方法
  • 不要把promise写成嵌套

题目

  • 3秒之后亮一次红灯,再过2秒亮一次绿灯,再过1秒亮一次黄灯,用promise实现多次交替亮灯的效果

拆解:

  1. 多少秒后亮某个颜色的灯
  2. 顺序亮一批灯
  3. 循环顺序亮一批灯
function light(color,second){
  return new Promise(function(resolve,reject){
    setTimeout(function(){
      console.log(color);
      resolve();
    },second * 1000);
  });
}

//[{color:xx,second:xx}]
function orderLights(list){
  let promise = Promise.resolve();
  list.forEach(item => {
    promise = promise.then(function(){
      return light(item.color,item.second);
    });
  });
  promise.then(function(){
    return orderLights(list);
  })
}

orderLights([{
  color:'red',
  second:3,
},{
  color:'green',
  second:3,
},{
  color:'yellow',
  second:3,
}]);

课后习题

  • 根据Promise/A+规范实现promise,使用promises-aplus/promises-tests插件验证
  • 找一些promise的面试题
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容