【问题标题】:Async await code does not running the same way with forEach异步等待代码的运行方式与 forEach 不同
【发布时间】:2019-09-27 05:11:35
【问题描述】:

我有这段代码,当我运行时,它会按顺序运行“一”和“二”。

所以下面的代码可以正常工作。

(async () => {

  await runit('one').then(res => {
    console.info(res);
  });

  await runit('two').then(res => {
    console.info(res);
  });

})();

现在,我想在循环中做同样的事情,所以我这样做了:

const arr = ['one', 'two'];
  arr.forEach(element => {
    (async () => {
      await runit(element).then(res => {
      console.info(res);
    });
  })();
});

虽然看起来是相同的代码,但它不再按照顶部代码的顺序运行。

我该如何解决这个问题?

【问题讨论】:

  • 您的第一个示例更像(以简化的方式):runit('one').then(() => runit('two))
  • 这是一个使用基本for 循环的解决方案:jsfiddle.net/khrismuc/a7htxg3y

标签: javascript node.js typescript async-await


【解决方案1】:

您可以使用promise.all 函数实现相同的功能,如下所示。

const arr = ['one', 'two'];
const promises = [];
  arr.forEach(element => {
      promises.push(runit(element));
  });

Promise.all(promises).then(results => {
    console.log(results)//you will get results here.
});

【讨论】:

  • 虽然在某些情况下很好,但这并不能保证承诺会按时间顺序解决(第一个解决,然后第二个......)
  • runit() 显然返回一个Promise。将这个承诺传递给Promise.resolve() 的原因是什么?
  • 它将解析与数组索引完全相同的顺序。我的意思是解决的值将在相同的承诺索引上收到。
  • @Andreas 收集承诺。这样我们就可以使用promise.all() 一次性解决所有承诺。
  • @Andreas 是的,Promise.resolve 完全是多余的。
【解决方案2】:

它不会等待,因为您执行的函数是异步的,您实际上是在告诉它不要等待。要修复它,你可以做简单的循环:

for (let i = 0; i < arr.length; i++) {
  const item = arr[i];
  await runit(item).then(res => {
    console.info(res);
  });
}

或者你可以使用 map 和 Promise.all:

const promises = arr.map(item => runit(item)));
const values = Promise.all(promises);
values.forEach(res => console.info(res))

后者是首选。

【讨论】:

  • 后者并行运行,而前者不并行。
【解决方案3】:

避免使用forEachawait。它不会正常工作。

forEach 忽略它所接受的回调函数的所有结果。如果您将 async 函数或任何其他返回承诺的函数传递给它,则所有返回的承诺都将未处理。

改用本机 for 循环。 要匹配一次只运行一项的非循环代码,请执行以下操作:

for (const element of ['one', 'two']) {
  console.log(await runit(element));
}

这与Promise.all 的其他答案大不相同。 Promise.all 等待多个承诺的批量完成,这意味着事情已经在并行运行。

要并行运行,请执行以下操作:

for (const res of await Promise.all(['one', 'two'].map(runit)) {
  console.log(res);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多