一、 什么是 Promise
Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。是目前比较流行Javascript异步编程解决方案之一。
二、promise A+ 规范
参考 promise A+ 官方,对promise A+规范做个翻译整理。
1.术语
- 1.1. promise: 是一个拥有
then方法的对象或函数,行为符合这个规范。 - 1.2. thenable: 是一个
then方法的对象或函数。 - 1.3. value: 是promise状态成功的时的值(resolve参数),包括各种数据类型(如
undefined,thenable,promise等)。 - 1.4. exception: 是一个使用
throw语句抛出的一个值 - 1.5. reason: 是
promise状态失败的值(reject参数),表示为什么被拒绝
2.要求
2.1 Promise 状态
promise 的当前状态必须是以下三种状态中的一种:pending,fulfilled或rejected ,要注意他们之间的流转关系.
-
pending等待态是初始的状态,在
resolve或reject前都是这个状态。可改变为fulfilled状态 和rejected状态。 -
fulfilled解决态是最终态,不可变。
promise在resolve后会变成这个状态。必须有一个不能改变的值 value -
rejected拒绝态是最终态,不可变。
promise在reject后会变成这个状态。必须有一个不能改变的值 reason
2.2 then 方法
promise应该提供一个then方法, 用来访问最终的结果(无论是value还是reason).
promise的then方法接受俩个参数:
promise.then(onFulfilled, onRejected)
-
onFulfilled和onRejected都是可选的参数1.1 如果
onFulfilled不是函数类型, 必须被忽略.1.2 如果
onRejected不是函数类型, 必须被忽略. -
如果
onFulfilled是函数,它的特性:2.1 在
promise变成fulfilled后调用onFulfilled,value作为它的第一个参数2.2 在
promise变成fulfilled之前,不能被调用2.3 只能被调用一次
-
如果
onRejected是函数,它的特性3.1 在
promise变成rejected后调用onRejected,reason作为他的第一个参数3.2 在
promise变成rejected之前, 不能被调用3.3 只能被调用一次
-
onFulfilled和onRejected调用时机和调用要求4.1
onFulfilled和onRejected只有在执行环境堆栈仅包含平台代码时才可被调用(onFulfilled和onRejected应该是微任务)4.2
onFulfilled和onRejected必须被作为函数调用(即没有this值) -
then方法可以被调用多次5.1
promise状态变成fulfilled后,所有的onFulfilled回调均按照初始调用顺序执行(即按照then的顺序执行,实现时用一个数组来存放多个onFulfilled的回调)5.2
promise状态变成rejected后,所有的onRejected回调均按照初始调用顺序执行(即按照then的顺序执行,实现时用一个数组来存放多个onRejected的回调) -
then方法 必须返回一个promisepromise2 = promise1.then(onFulfilled, onRejected);6.1
onFulfilled或onRejected执行返回的结果为x, 则运行下面的 Promise 解决过程[[Resolve]](promise2, x)(这里我们简述为:调用 resolvePromise)6.2 如果
onFulfilled或者onRejected执行时抛出异常e,promise2必须被reject,并返回reason作为e6.3 如果
onFulfilled不是一个函数,并且promise1执行fulfilled,promise2以promise1的value触发fulfilled6.4 如果
onRejected不是一个函数,并且promise1执行rejected,promise2以promise1的reason触发rejected
2.3. Promise 解决过程(上面提到的 resolvePromise)
[[Resolve]](promise2, x)
// 我们自己实现写成下面这样
resolvePromise(promise2, x, resolve, reject)
-
如果
promise2和x引用同一个对象,那么reject的promise会并用TypeError作为reason -
如果
x是一个promsie如果 x 处于 pending态,那么promise必须要保持pending,直到 x 变成 fulfilled or rejected. 如果 x 被 fulfilled, fulfill promise with the same value. 如果 x 被 rejected, reject promise with the same reason. -
如果
x是object或者function3.1 把
x.then赋值给then(let then = x.then)3.2 如果 取
x.then抛出错误e,那么 reject promise with e as the reason.3.3 如果
then是一个函数,将x作为函数的作用域this调用之。then.call(x, resolvePromiseFn, rejectPromise)1 resolvePromiseFn 的 入参是 y, 执行 resolvePromise(promise2, y, resolve, reject); 2 rejectPromise 的 入参是 r, reject promise with r. 3 如果 resolvePromise 和 rejectPromise 都调用了,那么第一个调用优先,后面的调用忽略。 4 如果调用then抛出异常e 如果 resolvePromise 或 rejectPromise 已经被调用,那么忽略 则,reject promise with e as the reason 5 如果 then 不是一个函数. fulfill promise with x.