【问题标题】:async await promise all versus storing in a variableasync await promise all 与存储在变量中
【发布时间】:2021-03-03 15:40:39
【问题描述】:

我正在查看 MDN documentation 的异步等待,发现有一个 promise.all 的替代方案

所以,

如果 coffeeteadescription 是三个承诺,我们可以全部等待

let values = await Promise.all([coffee, tea, description]);

但是 MDN 也给出了慢速和快速异步等待的例子:

慢速异步等待示例:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

快速异步等待示例:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

我对快速异步等待感到困惑。它是否类似于promise.all()?是不是比promise.all()?更好

如果我们在不同的行中编写多个等待,它与慢速异步等待有什么不同?

【问题讨论】:

  • "它的工作原理是否类似于 promise.all()?" 基本上适用于更简单的场景 - 是的。 “比 promise.all() 更好吗?”定义“更好”。
  • Promise.all 如果您不知道需要等待多少个承诺,这很好。什么是“慢速异步等待”?
  • “快”方法的优点是它并行运行进程,而“慢”方法串联运行它们。 Promise.all 也并行运行。

标签: javascript asynchronous async-await


【解决方案1】:

这个sn-p:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

只有在最后一个 Promise 完成后才会初始化每个 Promise。

  • 初始化第一个 Promise
  • 等待它完成(3 秒)
  • 初始化第二个 Promise (...等)

相比之下,这个sn-p:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

将一次初始化所有的 Promise。然后,它会

  • 等待第一个 Promise 解决
  • 等待第二个 Promise 解决
  • 等待第三个 Promise 解决

但是第二个 sn-p 有一个严重的缺陷:如果其中一个 Promise 碰巧被拒绝,它可能会导致一个未处理的拒绝,尽管它前面有一个 await。例如,如果timeoutPromise1 尚未解决,而timeoutPromise2 拒绝:

window.addEventListener('unhandledrejection', () => {
  console.error('Unhandled rejection :(');
});

async function timeTest() {
  const timeoutPromise1 = new Promise(resolve => setTimeout(resolve, 5000));
  const timeoutPromise2 = new Promise((resolve, reject) => setTimeout(reject, 500));
  
  await timeoutPromise1;
  await timeoutPromise2;
}

timeTest()
  .catch((error) => {
    console.log('Error caught');
  });

出现这个问题是因为 Promise 必须是 awaited 或有一个 .catch 链接到它在它拒绝的点。如果它在.catchawait 连接到它之前拒绝,则会导致未处理的拒绝。

未处理的拒绝,就像未处理的错误一样,是丑陋的,应该避免。在 Node 中,未处理的拒绝不仅不好,它们也已被弃用,并且可能使 Node 进程完全崩溃。

因此,使用Promise.all 是比第二个 sn-p 更好的方法。

【讨论】:

  • 另外值得注意的是,'promise 中的函数在 promise 初始化后立即执行,await 意味着在等待等待的 promise 被解决或拒绝之前,同一范围内的后续行将不会运行'...
  • 既然你说它会立即初始化所有承诺并等待每一行,你是说它不像其他答案所暗示的那样并行运行?
  • @SeyiShoboyejo 好的,这解释了很多。谢谢!
  • @goxarad784 Promise 是一次初始化的,所以它们都是并行运行的,但它们的解决方案是串行等待的。如果没有拒绝,它将与Promise.all 相同。
猜你喜欢
  • 2020-02-05
  • 2019-11-02
  • 2022-09-30
  • 1970-01-01
  • 2018-01-14
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 2018-06-27
相关资源
最近更新 更多