如何在 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);
});
}
如您所见,我们有一个用户名数组和一个接受参数并返回字符串的函数。
现在我们将使用 map 方法迭代用户名数组以获取每个用户的模拟数据:
const dataUsers = usernames.map(async (username) => {
return await simulateFetchData(username);
});
console.log(dataUsers);
但是执行此操作时,我们将在控制台中看到以下结果:
[ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
因此,为了解决这个问题,我们有两个选择,一个是使用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();
使用此选项,代码将按顺序执行,因此您可以等待每次调用。这将帮助我们在进行下一次迭代之前解决每次迭代的问题。
请记住,如果我们进行 N 次迭代,每次迭代都需要 1 秒才能完成(就像我们的例子一样),这意味着执行完这部分代码总共需要 3 秒。我们可以借助 console.time 在控制台输出中看到这一点:
for of: 3,012s
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();
如您所见,我们有一个 Promise.all 方法,它接收一个承诺数组,请记住,它usernames.map(async (username) => {return await simulateFetchData(username);})
返回一个承诺数组,这正是我们所需要的,因此我们将它传递给 Promise.all 来解决它们。
该方法将导致所有异步代码被并行解析。
因此,与 for of 不同,让我们看看在控制台中执行此函数需要多长时间:
promise all: 980.3000000119209ms
因此,如果我们有 N 个异步函数,它们将被执行和解析,而无需在它们之间等待,这在某些特定情况下非常有用。
有时出于性能原因,我们需要使用 Promise.all 并行执行 Promise,有时则需要使用 for of 循环按顺序执行。重要的是,你要了解它们之间的区别,以及如何根据你的需求进行调整。
如果您有任何问题或建议,请不要忘记发表评论,我们很快会再见 :)
您可以在此 codesandbox 存储库中查看完整代码
文章来源:https://dev.to/jordandev/how-to-use-asyncawait-with-map-in-js-2ena