在做代码审查时,我最近遇到了这样的代码块:
const promises = [];
const data = [];
for (let piece of pieces) {
for (let chunk of piece) {
promises.push(execute(chunk)); //execute returns a promise which is not yet fulfilled
}
data = await Promise.all(promises);
}
这里的 pieces
是一个数组的数组。请注意,由于某些限制,我们无法立即等待
所有 Promise,因此需要进行这种分块。
在我的反馈中,我写道这似乎是一种反模式,因为我们也在等待 Promises 在之前的迭代中已解决,以下是处理此类情况的正确方法:
const data = [];
for (let piece of pieces) {
const promises = [];
for (let chunk of piece) {
promies.push(execute(chunk)); //execute returns a promise which is not yet fulfilled
}
data.push(... await Promise.all(promises));
}
最后,data
在两种情况下都是相同的。
我了解在这两种情况下如何填充 data
。我想知道等待已经实现的 promise (发生在第一个代码块中)的性能开销是多少,它是否重要?
最佳答案
开销很小 - 它需要迭代已经实现的 promise ,检查它,取出数据并将其放入结果数组中。假设 native promise ,我希望这会得到优化并且不需要往返事件循环,如果您在数组中有 thenables 那么所有这些都需要解决一个 promise 并且需要异步等待该 promise ,采取对 promise 工作队列的收费。
与在 execute
函数中完成的实际异步工作相比,处理时间的开销并不显着。
但是,无论开销多小,第一个版本代码的问题在于它的运行时复杂度是二次方的:Promise.all
需要迭代整个 promises
数组每次。您拥有的 block * block 越多,效果就越明显。我同意您的评论反馈,并会推荐第二版代码。
关于javascript - 等待一个已经完成的 Promise 的性能开销是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53455835/