首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >等待递归调用异步函数的函数

等待递归调用异步函数的函数
EN

Stack Overflow用户
提问于 2020-05-21 19:19:56
回答 1查看 56关注 0票数 1

我有一个函数,看起来像这样:

代码语言:javascript
复制
function populateMap(directory: string, map, StringMap) {
    fs.promises.readdir(directory).then(files: string[]) => {
        files.forEach(file: string) => {
            const fullPath = path.join(directory, file);
            fs.stat(fullPath, (err: any, stats: any) => {
                if (stats.isDirectory()) {
                   populateFileMap(fullPath, fileMap);
                } else {
                   fileMap[file] = fullPath;
                }
            });
        });
    });
}

我想要做的是递归地遍历父目录,并存储文件名到它们的路径的映射。我知道这是有效的,因为如果我将一个console.log(fileMap)放在fileMapfile = fullPath下,在目录中最深的文件之后,列表就会被正确地填充。

在调用此函数的文件中,我希望能够获得完整的映射

代码语言:javascript
复制
function populateMapWrapper(dir: string) {
    const fileMap: StringMap = {};

    populateMap(dir, fileMap);

    //fileMap should be correctly populated here
}

我已经尝试使populateMap异步,在包装器函数中调用它的地方添加了一个.then(),但是如果我在then()函数中使用console.log( fileMap ),fileMap就是空的。

我不确定这是因为javascript传递变量的方式,还是在我对promises的理解上存在差距,但我想知道是否有其他方法可以做到这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-21 19:27:04

一个问题是fs.stat不返回承诺。您还需要使用fs.promises.stat。此外,在使用promises时要小心使用forEach,因为它不会为每个forEach回调使用await。您可以将mapPromise.all()一起使用

一种解决方案:

代码语言:javascript
复制
function populateMap(directory: string, map) {
  return fs.promises.readdir(directory).then((files: string[]) => {
    return Promise.all(
      files.map((file: string) => {
        const fullPath = path.join(directory, file);
        return fs.promises.stat(fullPath).then(stats => {
          if (stats.isDirectory()) {
            return populateMap(fullPath, map);
          } else {
            map[file] = fullPath;
          }
        })
      }))
  })
}

然后,您必须在包装器中使用await

代码语言:javascript
复制
async function populateMapWrapper(dir: string) {
    const fileMap: StringMap = {};

    await populateMap(dir, fileMap);

    //fileMap should be correctly populated here
}

但是,一种更具可读性的解决方案是尽可能使用await。类似于:

代码语言:javascript
复制
async function populateMap (directory: string, map) {
  const files = await fs.promises.readdir(directory)
  for (const file of files) {
    const fullPath = path.join(directory, file)
    const stats = await fs.promises.stat(fullPath)
    if (stats.isDirectory()) {
      await populateMap(fullPath, map)
    } else {
      map[file] = fullPath
    }
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61933348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档