据我了解,在 ES7/ES2016 中,在代码中放置多个 await
的工作方式类似于使用 Promise 链接 .then()
,这意味着它们将一个接一个地执行,而不是并行执行。因此,例如,我们有以下代码:
await someCall();
await anotherCall();
我是否正确理解 anotherCall()
只有在 someCall()
完成时才会被调用?并行调用它们的最优雅方式是什么?
我想在Node中使用它,所以也许有异步库的解决方案?
编辑:我对这个问题中提供的解决方案不满意:Slowdown due to non-parallel awaiting of promises in async generators ,因为它使用了生成器,我问的是更一般的用例。
最佳答案
你可以在 Promise.all()
上等待:
await Promise.all([someCall(), anotherCall()]);
存储结果:
let [someResult, anotherResult] = await Promise.all([someCall(), anotherCall()]);
请注意,Promise.all
很快就会失败,这意味着一旦提供给它的 promise 之一被拒绝,那么整个事情都会被拒绝。
const happy = (v, ms) => new Promise((resolve) => setTimeout(() => resolve(v), ms))
const sad = (v, ms) => new Promise((_, reject) => setTimeout(() => reject(v), ms))
Promise.all([happy('happy', 100), sad('sad', 50)])
.then(console.log).catch(console.log) // 'sad'
相反,如果您想等待所有的 promise 履行或拒绝,那么您可以使用 Promise.allSettled
.请注意,Internet Explorer 本身并不支持此方法。
const happy = (v, ms) => new Promise((resolve) => setTimeout(() => resolve(v), ms))
const sad = (v, ms) => new Promise((_, reject) => setTimeout(() => reject(v), ms))
Promise.allSettled([happy('happy', 100), sad('sad', 50)])
.then(console.log) // [{ "status":"fulfilled", "value":"happy" }, { "status":"rejected", "reason":"sad" }]
Note: If you use
Promise.all
actions that managed to finish before rejection happen are not rolled back, so you may need to take care of such situation. For example if you have 5 actions, 4 quick, 1 slow and slow rejects. Those 4 actions may be already executed so you may need to roll back. In such situation consider usingPromise.allSettled
while it will provide exact detail which action failed and which not.
关于javascript - 并行调用 async/await 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35612428/