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;
}
});
});
});
}
我想要做的是递归遍历父目录并将文件名映射存储到它们的路径。我知道这是有效的,因为如果我在 fileMap[file] = fullPath 下放置一个 console.log(fileMap),在目录中最深的文件之后,列表就会正确填充。
在调用此函数的文件中,我希望能够拥有完整的地图
function populateMapWrapper(dir: string) {
const fileMap: StringMap = {};
populateMap(dir, fileMap);
//fileMap should be correctly populated here
}
我尝试过使 populateMap 异步,将 .then() 添加到包装函数中调用它的位置,但是如果我在 then() 函数中使用 console.log(fileMap) ,则 fileMap 为空。
我不确定这是否是因为 javascript 如何传递变量,或者我对 Promise 的理解存在差距,但我想知道是否有其他方法可以做到这一点。
解决方案
一个问题是它fs.stat
不返回承诺。您还需要使用fs.promises.stat
. 此外,在使用 Promise 时要小心使用forEach
,因为它不适await
用于每个forEach
回调。您可以改为使用map
withPromise.all()
一种解决方案:
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
在包装器中使用:
async function populateMapWrapper(dir: string) {
const fileMap: StringMap = {};
await populateMap(dir, fileMap);
//fileMap should be correctly populated here
}
但是,一个更具可读性的解决方案是await
尽可能使用。就像是:
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
}
}
}
推荐阅读
- python - 是否可以将 python 多处理与 MS SQL Server 一起使用
- r - 计算连续的数字
- python - 为什么预言家预测(尤其是年度季节性)与情节组件中的年度季节性完全不同?
- javascript - pubnub心跳间隔对内存有影响吗?
- hive - 如何在 hive 的 select 语句中编写子查询
- powershell - 用于将属性从文件中间移动到文件末尾的 Powershell 脚本
- extjs - ExtJS 7 - 锁定列的列过滤器问题
- html - 使用基本 CSS对齐锚 ( ) 标签以显示在同一行
- google-cloud-platform - 是否有任何命令可以在一个只有顶部标题的单个 excel 文件中列出所有 GCP 项目配额
- javascript - 将 Teams 频道消息呈现为卡片