如何在 js 中将 async/await 与 .map 结合使用

2025-05-25

如何在 js 中将 async/await 与 .map 结合使用

如何在 js 中将 async/await 与 .map 结合使用

在某些时候,您可能想知道如何在 .map 或 .forEach 等方法中使用异步函数,因为在这篇小博客中,您将看到最常见的错误是什么以及如何解决它们。

为此,我们将在 index.ts 文件中添加以下基本代码:

const usernames: string[] = ["jordanrjdev", "anonymous123", "channelyy"];

const simulateFetchData = (username: string): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`${username} is a valid username`);
    }, 1000);
  });
}
Enter fullscreen mode Exit fullscreen mode

如您所见,我们有一个用户名数组和一个接受参数并返回字符串的函数。

现在我们将使用 map 方法迭代用户名数组以获取每个用户的模拟数据:

const dataUsers = usernames.map(async (username) => {
   return await simulateFetchData(username);
});
console.log(dataUsers);
Enter fullscreen mode Exit fullscreen mode

但是执行此操作时,我们将在控制台中看到以下结果:

[ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
Enter fullscreen mode Exit fullscreen mode

因此,为了解决这个问题,我们有两个选择,一个是使用Promise.all,另一个是使用for of

对于

我们将使用 for 来解决这个非常常见的错误,并且会让我们在尝试寻找最合适的解决方案时浪费大量时间。

const getWithForOf = async() => {
   console.time("for of");
   const data = []
   for (const username of usernames) {
     let dataUser = await simulateFetchData(username);
     data.push(dataUser);
   }
   console.timeEnd("for of");
}
getWithForOf();
Enter fullscreen mode Exit fullscreen mode

使用此选项,代码将按顺序执行,因此您可以等待每次调用。这将帮助我们在进行下一次迭代之前解决每次迭代的问题。

请记住,如果我们进行 N 次迭代,每次迭代都需要 1 秒才能完成(就像我们的例子一样),这意味着执行完这部分代码总共需要 3 秒。我们可以借助 console.time 在控制台输出中看到这一点:

for of: 3,012s
Enter fullscreen mode Exit fullscreen mode

Promise.all

现在我们将使用promise.all方法来解决我们的问题,因此我们将有以下代码:

const getWithPromiseAll = async() => {
   console.time("promise all");
   let data = await Promise.all(usernames.map(async (username) => {
     return await simulateFetchData(username);
   }))
   console.timeEnd("promise all");
}

getWithPromiseAll();
Enter fullscreen mode Exit fullscreen mode

如您所见,我们有一个 Promise.all 方法,它接收一个承诺数组,请记住,它

usernames.map(async (username) => {return await simulateFetchData(username);})

返回一个承诺数组,这正是我们所需要的,因此我们将它传递给 Promise.all 来解决它们。

该方法将导致所有异步代码被并行解析。

因此,与 for of 不同,让我们看看在控制台中执行此函数需要多长时间:

promise all: 980.3000000119209ms
Enter fullscreen mode Exit fullscreen mode

因此,如果我们有 N 个异步函数,它们将被执行和解析,而无需在它们之间等待,这在某些特定情况下非常有用。

有时出于性能原因,我们需要使用 Promise.all 并行执行 Promise,有时则需要使用 for of 循环按顺序执行。重要的是,你要了解它们之间的区别,以及如何根据你的需求进行调整。

如果您有任何问题或建议,请不要忘记发表评论,我们很快会再见 :)

您可以在此 codesandbox 存储库中查看完整代码

文章来源:https://dev.to/jordandev/how-to-use-asyncawait-with-map-in-js-2ena
PREV
您的图像必须具备 3 个属性!
NEXT
2020 年必须了解的 11 个前端趋势