遍历数组时使用异步方法

在遍历数组时,如果在对每个元素的回调中使用异步方法,不能使用 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() 中的顺序返回的。而第二种方法是同步执行,遍历完成一个才会遍历下一个,可以根据情况选择这两种方法。


转载规则

《遍历数组时使用异步方法》Konata 采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
  目录