如何将循环等待转换为 Promise.all?

Nic*_*oso 1 javascript promise async-await

我正在转换同事的一些旧代码,我对 Javascript 并不陌生,但我很生疏,而且我对 Promises、Map 和其他新的 JS 功能很陌生。

我需要将for带有 an 的循环转换为可以在更大的 Promise 链中使用的awaita 。Promise

我认为答案是Promise.alland a Map / Stream / Reduce(我仍在学习哪个是为了什么),但我看过的所有媒体文章都解释得很差(而且我可能不知道要搜索的正确内容)。

这是我要转换的代码:

//foos and bars are global and can be used in the `then` after this promise resolves, 
//  so what the promise returns is unimportant

for (let bar of bars) {
    foos[bar] = await new MyClass(bar).myAsyncOperation();
}
Run Code Online (Sandbox Code Playgroud)

如何转换循环,以便在循环中的所有项目完成之前承诺不会解析?

另外,我应该转换myAsyncOperation为返回 Promise 还是可以/应该将其保留为异步函数?

Nik*_*des 5

只需从您的 中创建一个新的 Promise 数组bars(最好使用 )Array.map,然后将该数组传递给Promise.all 即可获取其结果。

// Wrap main code in an async IIFE so we can use await.
(async () => {
  let bars = [1,2,3,4]

  // Sample async function which implicitly returns a Promise since it's marked
  // as async. Could also be a regular function explicitly returning a Promise.
  const myAsyncOperation = async bar => bar * 5

  // Create an array of Promises from bars.
  const tasks = bars.map(bar => myAsyncOperation(bar))

  try {
    // Pass the Promises to Promise.all and get results.
    const results = await Promise.all(tasks)

    console.log(results)
  } catch (err) {
    console.error(err)
  }
})()
Run Code Online (Sandbox Code Playgroud)

for..of与您的示例的区别在于,它Promise.all不会等待每个单独的 Promise 解决后再继续下一个 Promise。它或多或少是并行的,而不是顺序的。

...另外,我应该将 myAsyncOperation 转换为返回 Promise 还是可以/应该将其保留为异步函数?

好吧,如果myAsyncOperation是一个async标记函数,那么它已经返回一个Promise。将函数标记为async会导致它始终隐式返回 a Promise