这两者之间有什么区别吗:
const promises = await Promise.all(items.map(e => somethingAsync(e)));
for (const res of promises) {
// do some calculations
}
这个呢
for await (const res of items.map(e => somethingAsync(e))) {
// do some calculations
}
我知道在第一个代码片段中,所有的promise都是同时触发的,但我不确定第二个代码片段是否如此。for循环是否等待第一次迭代完成后才调用下一个promise?或者所有的promise都是同时触发的,循环内部的行为就像是对它们的回调?
4条答案
按热度按时间5f0d552i1#
是的,他们绝对是不同的。
for await
应该与异步迭代器一起使用,而不是与预先存在的promise数组一起使用。我先说清楚
工作原理与
或
somethingAsync
调用立即发生,所有的调用都是在等待任何事情之前发生的。然后,它们一个接一个地被await
艾德,如果其中任何一个被拒绝,这肯定是一个问题:它将导致未处理Promise拒绝错误。使用Promise.all
是处理promise数组的唯一可行选择:有关详细信息,请参见Waiting for more than one concurrent await operation和Any difference between await Promise.all() and multiple await?。
wqnecbli2#
当在异步迭代器上,当前迭代的计算依赖于以前的一些迭代时,就需要
for await ...
。如果没有依赖关系,则选择Promise.all
。for await
结构是设计用于异步迭代器的,尽管在示例中,您可以将其与promise数组一起使用。请参阅javascript.info一书中的分页数据示例,其中使用了不能用
Promise.all
重写的异步迭代器:在这里,
fetchCommits
异步迭代器向fetch
请求GitHub存储库的提交。fetch
使用30次提交的JSON进行响应,并在Link
头中提供指向下一页的链接。因此下一次迭代只能在上一次迭代具有下一次请求的链接后才能开始fcipmucu3#
正如你所说的,
Promise.all
将一次性发送所有请求,然后当所有请求都完成时,你会得到响应。在第二个场景中,您将一次性发送请求,但会逐个接收响应。
看这个小例子作为参考。
你也可以在这里试试-https://repl.it/repls/SuddenUselessAnalyst
希望这能帮上忙。
iaqfqrcu4#
实际上,使用
for await
语法确实会一次触发所有promise。下面的代码证明了这一点:
stdout:
time: 4.001
但是循环内部并不充当回调函数。如果我反转数组,所有日志会同时出现。我假设Promise会立即被触发,运行时只需要等待第一个Promise解决,然后进入下一次迭代。
编辑:实际上,使用
for await
是不好的做法,当我们使用它与异步迭代器以外的东西,最好是使用Promise.all
,根据@Bergi在他的回答。