术语
- promise是一个有then方法的对象或者是函数,行为遵循本规范
- thenable是一个有then方法的对象或是函数
- value是promise状态成功时的值,也就是resolve的参数,包括各种数据类型,也包括undefined/thenable或者是promise
- reason 是promise状态失败时的值,也就是reject的参数,表示拒绝的原因
- exception是一个使用throw抛出的异常值
规范
promise status
promise应该有三种状态,要注意他们之间的流转关系
1.pending
1.1 初始状态,可改变
1.2一个promise在resolve或者reject前都处于这个状态
1.3可以通过 resolve -> fulfilled 状态
1.4可以通过reject -> rejected 状态
2.fulfilled
2.1 最终态,不可变
2.2 一个promise被resolve后会变成这个状态
2.3 必须有一个value值(不传为undefined)
3.rejected
3.1最终态,不可变
3.2一个promise被reject后会变成这个状态
3.3 必须拥有一个reason值
Tips:总结一下,promise的流转状态
pending --> resolve(value) --> fulfilled
pending --> reject(reason) --> rejected
then
promise应该提供一个then方法,用来访问最终的结果,无论是value还是reason
promise.then(onFulfilled,onRejected)
- 参数要求
onFulfilled、onRejected必须是函数类型,如果不是函数,应该被忽略
- onFulfilled特性
2.1 在promise变成fulfilled时,应该调用onFulfilled,参数是value
2.2 在promise变成fulfilled之前,不应该被调用
2.3 只能被调用一次(所以在实现的时候需要一个变量来限制执行次数)
- onRejected特性
3.1 在promsie变成rejected时,应该调用onRejected,参数是reason
3.2 在promise变成rejected前之前,不应该被调用
3.3 只能调用一次(所以在实现的时候需要一个变量来限制执行次数)
- onFufilled和onRejected应该是微任务
这里用queueMicrotask来实现微任务的调用
- then方法可以被调用多次
5.1 proimise状态变成fulfilled后,所有的onFulfilled回调都需要按照then的顺序执行,也就是按照注册的顺序执行(所以在实现的时候需要一个数组来存放多个onFulfilled的回调)
5.2 promise状态变成rejected后,所有的onRejected回调都需要按照then的顺序执行,也就是按照注册顺序执行(所以在实现的时候需要一个数组来存放多个onRejected的回调)
- 返回值
promise2 = promise1.then(onFulfilled,onRejected)
6.1 onFulfilled或 onRejected执行的结果为x,调用resolvePromise
6.2 如果onFulfilled 或者 onRejected执行时抛出异常e,promise2需要被reject
6.3 如果onFulfilled不是一个函数,promise2以promise1的value触发fulfilled
6.4 如果onRejected不是一个函数,promise2以promise1的reason触发rejected
- resolvePromise
resolvePromise(promise1,x,resolve,reject)
7.1 如果promise2和x相等,那么rejectTypeError
7.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
7.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 或 rejectPromise 已经被调用,那么忽略
则,reject promise with e as the reason
如果 then 不是一个function. fulfill promise with x.
(后续继续更新及手写promise)