Promise.allSettled()、Promise.any() polyfill

Promise.allSettled()方法返回一个在所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个 promise 的结果时,通常使用它。相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个 reject 时立即结束。

Promise.allSettled()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Promise.allSettled =
Promise.allSettled ||
function (arr) {
var P = this
return new P(function (resolve, reject) {
if (Object.prototype.toString.call(arr) !== '[object Array]') {
return reject(
new TypeError(typeof arr + ' ' + arr + ' ' + ' is not iterable(cannot read property Symbol(Symbol.iterator))')
)
}
var args = Array.prototype.slice.call(arr)
if (args.length === 0) return resolve([])
var arrCount = args.length

function resolvePromise(index, value) {
if (typeof value === 'object') {
var then = value.then
if (typeof then === 'function') {
then.call(
value,
function (val) {
args[index] = { status: 'fulfilled', value: val }
if (--arrCount === 0) {
resolve(args)
}
},
function (e) {
args[index] = { status: 'rejected', reason: e }
if (--arrCount === 0) {
resolve(args)
}
}
)
}
}
}

for (var i = 0; i < args.length; i++) {
resolvePromise(i, args[i])
}
})
}

Promise.any()接收一个 Promise 可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和 AggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和 Promise.all()是相反的。

Promise.any()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Promise.any =
Promise.any ||
function any(promises) {
return Promise.all(
promises.map(promise =>
promise.then(
val => {
throw val
},
reason => reason
)
)
).then(
reasons => {
throw reasons
},
firstResolved => firstResolved
)
}