【发布时间】:2018-08-12 12:07:07
【问题描述】:
我有一个库,可以扫描远程服务器上的文件目录。它返回一个这样的 Promise:
client.scanRemoteDirectory(path)
.then(files => {
console.log(files)
})
我也在尝试编写一个递归方法来扫描目录和子目录。但我遇到了一些异步问题。我的功能是这样的:
const scanDir(path) {
// Scan the remote directory for files and sub-directories
return client.scanRemoteDirectory(path)
.then(files => {
for (const file of files) {
// If a sub-directory is found, scan it too
if (file.type === 'directory') {
return scanDir(file.path) // Recursive call
}
}
})
}
const scanDir('some/path')
.then(() => {
console.log('done')
})
但是,由于scanDir() 递归方法调用前面的return,这会导致该方法仅扫描每个目录中的第一个子目录并跳过其余子目录。
例如,如果结构是这样的:
/some/path
/some/path/dirA
/some/path/dirA/subdirA
/some/path/dirB
/some/path/dirB/subdirB
上述方法只会扫描:
/some/path
/some/path/dirA
/some/path/subdirA
它将跳过 dirB 和它的孩子,因为该方法首先找到 dirA。
如果我只是从return scanDir(...) 调用中删除return,那么它会很好地扫描所有内容。但是我最后的console.log('done') 发生得太快了,因为它是异步的。
那么我该如何解决这个问题呢?什么是正确的递归 Promise 方法,我仍然可以保留异步但还可以递归扫描每个子目录?
【问题讨论】:
-
就个人而言,我会使用
promise.all而不是 foreach 循环来解决这个问题。简而言之,创建一个承诺数组,循环“文件”数组,将每个承诺推送到数组并调用promise.all。这样,无论有多少个promise被递归链接,父promise只有在children有的时候才会被resolve。另外,我会手动处理链顶部的Promise对象。总结一下,创建数组,推送承诺并执行return Promise.all(array)。但请注意,因为响应会略有不同。 -
感谢 Promise.all 的来电。返回 Promise.all 而不是 Promise 效果很好。谢谢,
标签: javascript node.js asynchronous recursion promise