async/await 是 JavaScript 中用于处理异步操作的一种语法糖。它可以使异步代码看起来更像同步代码,从而更容易阅读和编写。
forEach 是一种用于遍历数组的方法。它接受一个回调函数作为参数,并对数组中的每个元素调用该函数。
async/await 不能直接用于 forEach 循环中,因为 forEach 不会等待回调函数返回的 Promise 完成。如果在 forEach 中使用 async/await,循环将不会等待异步操作完成就开始下一个迭代。这会导致意想不到的行为,如果您希望每个迭代在开始下一个迭代之前完成。
要修复此问题,您可以使用 for 循环、for…of 循环或 map() 函数与 async/await 一起使用,以实现所需的异步行为。
以下是在 forEach 循环中使用 async/await 的示例:
// 注意!这是无效的代码!
const files = await getFilePaths();
files.forEach(async file => {
const contents = await fs.readFile(file, "utf8");
console.log(contents);
});
这段代码可能不会做您期望的事情。它只是启动多个异步调用,但并不等待异步操作完成。
要按顺序读取文件,只需使用一个现代的 for…of 循环,其中 await 将按预期工作:
async function printFiles() {
const files = await getFilePaths();
for (const file of files) {
const contents = await fs.readFile(file, "utf8");
console.log(contents);
}
}
要并行读取文件,您只需使用 map,您就可以等待使用 Promise.all 获得的 Promise 数组:
async function printFiles() {
const files = await getFilePaths();
await Promise.all(
files.map(async file => {
const contents = await fs.readFile(file, "utf8");
console.log(contents);
})
);
}