淘先锋技术网

首页 1 2 3 4 5 6 7

相信很多前端都对promise非常熟悉,对于promise的特性也都有一定的理解,但是说到手动实现promise,这对不少人应该是一个挑战,莫急,复杂的事其核心往往很简单,复杂是因其容错处理的解决思路。
要手动实现promise就不得不来了解promiseA+规范了。

promise/A+规范

在学习promise/A+规范前我们先了解一下术语,以便理解下面规范中的统一概念

1,promise是一个有then方法的对象或函数,行为遵循本规范
2,thenable 是一个有then方法的对象或者是函数
3,value是promise状态成功时的值,也就是resolve的参数,包括更熟数据类型,也包括undefined/thenable或者是promise
4,reason是promise状态失败时的值,也就是reject的参数,表示拒绝的原因
5,exception是一个使用throw抛出的异常值

接下来将分下面几部分来阐述promise/A+规范

Promise status
promise有三种状态,我们要注意他们之间的流转关系

pending

  1. 初始的状态,可改变
  2. 一个promise在resolve或者reject前都处于这个状态
  3. 可以通过resolve===》fulfilled状态
  4. 可以通过reject===》rejected状态

fulfilled

  1. 最终态,不可变
  2. 一个promise被resolve后会变成的状态
  3. 必须拥有一个value值

rejected

  1. 最终态,不可变
  2. 一个promise被reject后会变成的状态
  3. 必须拥有一个reason

Tips:总结,promise状态流转过程
pending -> resolve(value) -> fulfilled
pending -> reject(reason) -> rejected

then
promise提供的一个then方法,用来访问最终结果,无论是value还是reason
如:

参数要求

  1. onFulfilled必须是函数类型,如果不是函数,应被忽略
  2. onRejected必须是函数类型,如果不是,应被忽略

onFulfilled特性

  1. 在promise变成fulfilled时,应调用onFulfilled,参数为value
  2. 在promise变成fulfilled之前,不应该被调用
  3. 只能被调用一次

onRejected特性

  1. 在promise变成rejected时,应该调用onRejected,参数为reason
  2. 在promise变成rejected之前,不应被调用
  3. 只能被调用一次

onFulfilled和onRejected应是微任务,这里将使用queueMicrotask来实现微任务的调用

then方法可以被调用多次

  1. promise状态变成fulfilled后,所有的onFulfilled回调都需要按照then的顺序执行,也就是按照注册顺序执行
  2. promise状态变成rejected后,所有的onRejected回调都需要按照then的顺序执行,按照注册顺序执行

在实现过程中需要一个数组来存放多个onFulfilled或者是onRejected的回调

返回值
then应返回一个promise

  1. onFuifilled或者onRejected执行的结果为x,调用resolvePromise
  2. 如果onFulfilled或者onRejected执行时抛出异常e,promse2需要被reject
  3. 如果onFulfilled不是一个函数,promise2以promise1的value触发fulfilled
  4. 如果onRejected不是一个函数,promise2以promise1的reason触发rejected

resolvePromise

  1. 如果promise2与x相等,那么reject TypeError
  2. 如果x是一个promise。如果x是pending态,那么promise必须要在pending,直到x变成fulfilled or rejected;如果x被fulfilled,fulfill promise with the same value;如果x被rejected,reject promise with the same reason
  3. 如果x是一个object或者是一个function;let then=x.then ;如果x.then这步出错,那么reject promise with e as the reason;如果then是一个函数,then.call(x,resolvePromiseFn,rejectPromise),resolvePromiseFn的入参是y,执行resolvePromise(promise2,y,resolve,reject);rejectPromise的入参是r,reject promise with r.如果resolvePromise和rejectPromise都调用,那么第一个调用优先,后面调用忽略。如果调用then抛出异常e时,如果resolvePromise已经被调用,忽略,reject promise with e as then reason。如果then不是一个function,fulfill promise with x。

小伙伴们是否对resolvePromise的各个可能性分析有些疑惑和不解,莫急,我们一步一步来通过代码来辅助理解它。理解promise/A+规范,是我们手写promise的基础。下一章我们来手动实现promise.