// 与 Promise.all 不同的是,当 promise 被 reject 之后,我们不会直接 reject ,而是记录下该 reject 的值和对应的状态 'rejected' ;
// 同样地,当 promise 对象被 resolve 时我们也不仅仅局限于记录值,同时也会记录状态 'fulfilled' 。
// 当所有的 promise 对象都已执行(解决或拒绝),我们统一 resolve 所有的 promise 执行结果数组
function allSettled(promises) {
return new Promise((resolve, reject) => {
promises = Array.isArray(promises) ? promises : []
let len = promises.length
const argslen = len
// 如果传入的是空数组,直接返回一个resolve的空数组promise对象
if (len === 0) return resolve([])
// 将传入的参数转为数组,赋值给args变量
let args = Array.prototype.slice.call(promises)
for (let i = 0; i < argslen; i++) {
resolvePromise(i, args[i])
}
// 计算当前是否所有的promise都执行完成, 执行完成则resolve
const compute = () => {
if (--len === 0) {
resolve(args)
}
}
function resolvePromise(index, value) {
// 判断传入的是否是promise类型
if (value instanceof Promise) {
const then = value.then
then.call(value, val => {
args[index] = { status: 'fulfilled', val }
compute()
}, e => {
args[index] = { status: 'rejected', e }
compute()
})
} else {
args[index] = { status: 'fulfilled', value }
compute()
}
}
})
}
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) => {
setTimeout(reject, 1000, 'three');
});
allSettled([p1, p2, p3])
.then(values => {
console.log(values)
})
console