Promise.allSettled()
相对于 Promise.all
需要所有 promise
都成功时才 resolve
或者有一个失败时即reject
,Promise.allSettled
只关心所有 promise
是不是都被 settle
了,不管其是 rejected
状态的 promise
,还是非 rejected
状态(即fulfilled
)的 promise
, 我都可以拿到它的最终状态并对其进行处理。
Promise.allSettled
的结果数组中可能包含以下两种格式的数据
- {status:"fulfilled", value:result} 对于成功的响应
- {status:"rejected", reason:error} 对于 error
if (!Promise.allSettled) { Promise.allSettled = function (promises) { return new Promise(resolve => { const data = [], len = promises.length; let count = len; for (let i = 0; i < len; i += 1) { const promise = promises[i]; promise.then(res => { data[i] = { status: 'fulfilled', value: res }; }, error => { data[i] = { status: 'rejected', reason: error }; }).finally(() => { // promise has been settled if (!--count) { resolve(data); } }); } }); } }
测试下
const promise1 = Promise.resolve(3); const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo')); const promises = [promise2, promise1]; Promise.allSettled(promises). then((results) => results.forEach((result) => console.log(result.status))); // expected output: // "rejected" // "fulfilled"
另外,更加简便的,我们也可以根据 Promise.all
来实现 Promise.allSettled
思路是让 Promise.all
入参中的所有 promise
都映射为新的最终状态为 fulfilled
的 promise
(而新promise
的result
则根据原来promise
的状态为fulfilled/reject
来决定),这样就总是能让Promise.all
成功返回数组。
if (!Promise.allSettled) { Promise.allSettled = function (promises) { return Promise.all(promises.map(p => Promise.resolve(p).then(res => { return { status: 'fulfilled', value: res } }, error => { return { status: 'rejected', reason: error } }))); }; }