我仍在尝试理解 Promise.all,因此编写了一个快速简单的脚本来查看 Promise.all 与使用 while 循环等待每个函数相比的性能差异。
我假设 Promise.all 会更快,因为它并行运行函数,但我的脚本似乎告诉我不然。
这是否太简单了,我错过了什么吗?
const p1 = async () => {
let x = 0
while(x < 100000000) {
x++
}
return x
}
const p2 = async () => {
let y = 100000000
while(y > 0) {
y--
}
return y
}
const p3 = async () => {
let z = 0
while(z < 200000000) {
z = z + 2
}
return z
}
const run1 = async () => {
console.time("Parallel")
const [res1, res2, res3] = await Promise.allSettled([p1(), p2(), p3()])
console.log(res1.value, res2.value, res3.value)
console.timeEnd("Parallel")
}
const run2 = async () => {
console.time("Sync")
const res1 = await p1()
const res2 = await p2()
const res3 = await p3()
console.log(res1, res2, res3)
console.timeEnd("Sync")
}
run1()
// run2()
结果
不要忘记 js 是单线程的,因此主线程上的计算是以牺牲其他函数为代价的,例如 p1 和 p2 “并行”运行,但在同一个事件循环上。
const expensiveComputation = async (nb) => {
let x = 0
while(x < nb*100*1000*1000) {x++}
return x
}
const expensiveComputationsParallel = async () => {
console.time("Expensive Parallel")
const [res1, res2, res3] = await Promise.all([
expensiveComputation(2),
expensiveComputation(3),
expensiveComputation(4)
])
console.timeEnd("Expensive Parallel")
}
const expensiveComputationsSynchronous = async () => {
console.time("Expensive Synchronous")
const res1 = await expensiveComputation(2)
const res2 = await expensiveComputation(3)
const res3 = await expensiveComputation(4)
console.timeEnd("Expensive Synchronous")
}
const lightComputation = async (timeMs) => {
return new Promise(resolve => {
timeout = setTimeout(() => {
resolve();
}, timeMs);
});
}
const lightComputationsParallel = async () => {
console.time("Light Parallel")
const [res1, res2, res3] = await Promise.all([
lightComputation(100),
lightComputation(200),
lightComputation(150)
])
console.timeEnd("Light Parallel")
}
const lightComputationsSynchronous= async () => {
console.time("Light Synchronous")
const res1 = await lightComputation(100)
const res2 = await lightComputation(200)
const res3 = await lightComputation(150)
console.timeEnd("Light Synchronous")
}
(async()=>{
await expensiveComputationsParallel()
await expensiveComputationsSynchronous()
await lightComputationsParallel()
await lightComputationsSynchronous()
})()
正如您在第二个示例中看到的,对于非计算密集型任务 Promise.all 需要的时间与其最长的 Promise 一样长,并且链接的时间与所有 Promise 的总和一样长。