寿司🍣 Promise 之 API (all, allSettled, any, race, resolve, reject)
寿司🍣 Promise 之 API (all, allSettled, any, race, resolve, reject)
分析异同点
首先,我们对这些 API 进行分析,提取他们的共同之处,和发现他们的不同之处。
共同点
- 参数都接受一个 promise 类型的
iterable
类型的输入(注:Array,Map,Set都属于ES6的inerable
类型) - 这些方法都返回一个
Promise
实例
不同点
返回的
Promise
实例的状态改变时机不同Promise.all
:在所有输入的 Promise 实例都resolve
后执行自身的resolve
回调,在任意一个输入的Promise实例reject
后执行自身的reject
回调Promise.allSettled
:在所有输入的 Promise 实例改变状态(resolve
或者reject
)后执行自身的resolve
回调Promise.any
:在所有输入的 Promise 实例都reject
后执行自身的reject
回调,在任意一个输入的Promise实例resolve
后执行自身的resolve
回调Promise.race
:在任意一个输入的Promise实例改变状态后以相同的状态改变自身
返回的Promise实例的终值(eventual value)或拒因(reason)不同
Promise.all
方法返回的Promise实例终值是一个数组,数组的成员是所有输入的 Promise 实例的终值,并按照参数内的 promise 顺序排列,而不是由调用 promise 的完成顺序决定。拒因是输入的 Promise 实例中第一个状态变为reject
的拒因Promise.allSettled
方法返回的 Promise 实例终值也是一个数组,并且按照参数内的promise
顺序排列。其中的每个成员在输入promise为resolved
状态时为{status:'fulfilled', value:同一个终值}
,rejected
状态时为{status:'rejected', reason:同一个拒因}
1
2
3
4
5
6
7
8const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).
then((results) => results.forEach((result) => console.log(result)));
// Object { status: "fulfilled", value: 3 }
// Object { status: "rejected", reason: "foo" }
参数为空迭代对象时,返回值不同
Promise.all
:同步地返回一个已完成(resolved)状态的promise
,其终值为空数组。(而且Promise.all
当且仅当传入的可迭代对象为空时是同步)Promise.allSettled
:与Promise.all
表现相同Promise.any
:同步地返回一个已失败(rejected)状态的 promise,其拒因是一个AggregateError
对象。Promise.race
:返回一个永远等待的promise
用同一个思路处理这些 API
根据上文的异同点分析,我们需要对参数进行判断是否为iterable
对象。定义一个结果收集数组和一个表示符合条件的 promise 状态个数变量,并且返回一个Promise
实例。
通用模板:
1 | function template(promises) { |
插播一下 Promise.resolve 这个函数:
Promise.resolve(value)方法返回一个以给定值解析后的 Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是 thenable(即带有”then” 方法),返回的 promise 会“跟随”这个 thenable 的对象,采用它的最终状态;否则返回的 promise 将以此值完成。
因为 promises 的成员里可能混入了一些不是 promise 的值,所以用 Promise.resolve 去解析后就能统一为其添加 then 回调了。
Promise.all
Promise.all:
- 传入的所有 Promsie 都是 fulfilled,则返回由他们的值组成的,状态为 fulfilled 的新 Promise
- 只要有一个 Promise 是 rejected,则返回 rejected 状态的新 Promsie,且它的值是第一个 rejected 的 Promise 的值
- 只要有一个 Promise 是 pending,则返回一个 pending 状态的新 Promise
1 | function all(promises) { |
Promise.allSettled
Promise.allSettled:
- 所有 Promise 的状态都变化了,那么新返回一个状态是 fulfilled 的 Promise,且它的值是一个数组,数组的每项由所有 Promise 的值和状态组成的对象
- 如果有一个是 pending 的 Promise,则返回一个状态是 pending 的新实例
1 | function allSettled(promises) { |
Promise.any
Promise.any:
- 空数组或者所有 Promise 都是 rejected,则返回状态是 rejected 的新 Promsie,且值为 AggregateError 的错误
- 只要有一个是 fulfilled 状态的,则返回第一个是 fulfilled 的新实例
- 其他情况都会返回一个 pending 的新实例
1 | function any(promises) { |
Promise.race
Promise.race:返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
1 | function race(promises) { |
Promise.resolve 和 Promise.reject
Promsie.resolve(value) 可以将任何值转成值为 value ,状态是 fulfilled 的 Promise,但如果传入的值本身是 Promise 则会原样返回它。
1 | // Promise.resolve |
1 | // Promise.reject |