gpt4 book ai didi

javascript - 基于 Promise 的递归目录读取

转载 作者:行者123 更新时间:2023-12-03 12:28:45 26 4
gpt4 key购买 nike

我有一个库,可以扫描远程服务器上的文件目录。它返回一个像这样的 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')
})

但是,由于 return 位于 scanDir() 递归方法调用前面,因此该方法有效,这会导致该方法仅扫描每个目录中的第一个子目录并跳过其余的。

例如,如果结构是这样的:

/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 来并行运行您的“子” promise ,例如:

function scanDir(path) {

return client.scanRemoteDirectory(path)
.then(all => {
const files = all.where(file => file.type !== 'directory);
const dirs = all.where(file => file.type === 'directory);
return Promise.all(dirs.map(dir => scanDir(dir.path)) // Execute all 'sub' promises in parallel.
.then(subFiles => {
return files.concat(subFiles);
});
});
}

或者,您可以使用 reduce 函数按顺序运行“子” promise :

function scanDir(path) {

return client.scanRemoteDirectory(path)
.then(all => {
const files = all.where(file => file.type !== 'directory);
const dirs = all.where(file => file.type === 'directory);
return dirs.reduce((prevPromise, dir) => { // Execute all 'sub' promises in sequence.
return prevPromise.then(output => {
return scanDir(dir.path)
.then(files => {
return output.concat(files);
});
});
}, Promise.resolve(files));
});
}

Async/await 绝对是最容易阅读的解决方案:

async function scanDir(path) {

const output = [];
const files = await client.scanRemoteDirectory(path);
for (const file of files) {
if (file.type !== 'directory') {
output.push(file);
continue;
}

const subFiles = await scanDir(file.path);
output = output.concat(subFiles);
}

return output;
}

关于javascript - 基于 Promise 的递归目录读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49100239/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com