在遍历数组时,如果在对每个元素的回调中使用异步方法,不能使用 forEach()
遍历。
错误的例子:
async function walkPath(path) {
let fileList = await fsPromises.readdir(path);
return new Promise(async (resolve) => {
await Promise.all(fileList.forEach(async (dirent) => {
await lookIntoFile(dirent.name);
}))
resolve();
})
}
正确的例子:
可以使用 map()
来代替 forEach()
:
async function walkPath(path) {
let fileList = await fsPromises.readdir(path);
return new Promise(async (resolve) => {
await Promise.all(fileList.map(async (dirent) => {
await lookIntoFile(dirent.name);
}))
resolve();
})
}
也可以使用 for ... of
遍历:
async function walkPath(path) {
let fileList = await fsPromises.readdir(path);
return new Promise(async (resolve) => {
for (const dirent of fileList) {
await lookIntoFile(dirent.name);
}
resolve();
})
}
以上两种方法,经过简单测试就能发现,第一种使用 map 遍历比下面使用 for ... of
遍历快得多。原因在于Promise.all()
中的对象是异步执行的,但它们的返回顺序还是按照 Promise.all()
中的顺序返回的。而第二种方法是同步执行,遍历完成一个才会遍历下一个,可以根据情况选择这两种方法。