all、allSettled 区别
两者的区别,就在于 all
必须是所有的 promise
的 status
都是 fulfilled
,才会执行后续代码,否则就会执行 catch
中的代码。而 allSettled
只要所有的 promise
的 status
不是 pending
就会执行后续代码。
async function getResolve(p) {
return new Promise(resolve => {
setTimeout(() => {
resolve({ result: p })
}, 1000)
})
}
async function getReject(p) {
return new Promise((_, reject) => {
setTimeout(() => {
reject({ result: p })
}, 1000)
})
}
// 例子1
;(async () => {
try {
const result = await Promise.all([getResolve(1), getResolve(2)])
console.log("result - all: ", result)
} catch (error) {
console.log("error - all: ", error)
}
})()
// 例子2
;(async () => {
try {
const result = await Promise.allSettled([
getResolve(1),
getResolve(2),
getReject(3)
])
console.log("result - allSettled: ", result)
} catch (error) {
console.log("error - allSettled: ", error)
}
})()
例子1的执行结果为:
error - all: { result: 3 }
例子2的执行结果为:
result - allSettled: [
{ status: 'fulfilled', value: { result: 1 } },
{ status: 'fulfilled', value: { result: 2 } },
{ status: 'rejected', reason: { result: 3 } }
]
比如我们并发请求了两个接口,其中一个成功了之后就可以将信息展示,就应该使用 allSettled
。
简单实现
Promise.prototype.all = function (values) {
return new Promise((resolve, reject) => {
const result = []
let index = 0
function processData(key, value) {
result[key] = value
index += 1
if (values.length === index) {
resolve(result)
}
}
for (let i = 0; i < values.length; i++) {
let current = values[i]
if (isPromise(current)) {
current.then(value => {
processData(i, value)
}, reject)
} else {
processData(i, current)
}
}
})
}
timeout 如何实现
可以使用 Promise.race
来实现。
;(async () => {
try {
const res = await Promise.race([getResolve(3), timeout()])
console.log("race result: ", res)
} catch (error) {
console.log("race error: ", error) // 执行结果: race error: timeout
}
})()
简单实现
Promise.prototype.race = function (promiseArr) {
return new Promise(function (resolve, reject) {
for (let promise of promiseArr) {
if (isPromise(promise)) {
promise.then(resolve, reject);
} else {
resolve(promise);
}
}
})
}
还有一个就是 promise.any
这个就是一定要等到一个 fulfilled
之后才会执行后面的代码。