在递归遍历目录时等待所有承诺都已解决

时间:2017-07-08 17:05:01

标签: javascript recursion promise

我正在尝试以递归方式遍历目录树并收集所有文件名。但是,在下面的代码中,最后的console.log()运行得太早,而不是等待函数的递归cacheDir调用生成的promise来解决:

function cacheDir(dir) {
  return fs.readdir(dir).then(items => {
    const readDirPromises = []

    for (let item of items) {
      const fullPath = path.join(dir, item)
      const lstat = fs.lstat(fullPath)
      readDirPromises.push(lstat)

      lstat.then(stats => {
        if (stats.isFile()) {
          return fullPath
        } else {
          return cacheDir(fullPath)
        }
      })
    }

    return Promise.all(readDirPromises)
  })
}

cacheDir("../someDir/")
  .then(results => console.log('done!', results))

我做错了什么?在我看来,readDirPromises将是strings和promises的数组,每个承诺本身将解析为一系列字符串和承诺。

1 个答案:

答案 0 :(得分:3)

您使用Promise.all()等待的承诺需要lstat.then(),而不仅仅是lstat。请记住,lstat.then()返回一个新的promise,并且新的promise会跟踪由于你的递归而需要从.then()处理程序返回的任何promise。

这是一个版本(并删除了一些临时变量):

function cacheDir(dir) {
  return fs.readdir(dir).then(items => {
    const readDirPromises = [];

    for (let item of items) {
      const fullPath = path.join(dir, item);

      readDirPromises.push(fs.lstat(fullPath).then(stats => {
        if (stats.isFile()) {
          return fullPath;
        } else {
          return cacheDir(fullPath);
        }
      }));
    }

    return Promise.all(readDirPromises)
  })
}