【发布时间】:2019-12-12 16:38:59
【问题描述】:
免责声明,自我回答的帖子,希望能节省其他人的时间。
设置:
我一直在使用 chrome 的文件系统 API 实现,[1][2][3]。
这需要启用标志chrome://flags/#native-file-system-api。
对于初学者,我想递归地读取目录并获取文件列表。这很简单:
paths = [];
let recursiveRead = async (path, handle) => {
let reads = [];
// window.handle = handle;
for await (let entry of await handle.getEntries()) { // <<< HANGING
if (entry.isFile)
paths.push(path.concat(entry.name));
else if (/* check some whitelist criteria to restrict which dirs are read*/)
reads.push(recursiveRead(path.concat(entry.name), entry));
}
await Promise.all(reads);
console.log('done', path, paths.length);
};
chooseFileSystemEntries({type: 'openDirectory'}).then(handle => {
recursiveRead([], handle).then(() => {
console.log('COMPLETELY DONE', paths.length);
});
});
我还实现了一个非递归的 while-loop-queue 版本。最后,我实现了一个节点fs.readdir 版本。所有 3 种解决方案都适用于小目录。
问题:
但后来我尝试在 chromium 源代码的一些子目录('base'、'components' 和 'chrome')上运行它; 3 个子目录总共包含约 63,000 个文件。虽然节点实现运行良好(令人惊讶的是,它在运行之间使用了缓存结果,导致在第一次运行后立即运行),但两个浏览器实现都挂起。
尝试调试:
有时,他们会返回完整的 63k 文件并按预期打印 'COMPLETLEY DONE'。但大多数情况下(90% 的时间)他们会在挂起之前读取 10k-40k 文件。
我更深入地研究了挂起,显然for await 行挂起。所以我在 for 循环之前添加了 window.handle = handle 行;当函数挂起时,我直接在浏览器控制台中运行了 for 循环,它工作正常!所以现在我被困住了。我似乎有随机挂起的工作代码。
【问题讨论】:
标签: javascript google-chrome chromium for-await native-file-system-api-js