必须用 Worker 做文件索引——因其拥有独立调用栈,可安全递归遍历深层嵌套结构,避免主线程卡死和栈溢出;主线程仅负责调度与结果聚合,保障 UI 响应。

直接用主线程递归搜索深层嵌套结构或海量文件元数据,极易触发 RangeError: Maximum call stack size exceeded,页面还会卡死。Worker 是唯一可行的解法——它把整个递归过程挪到独立线程,主线程只管发任务、收结果,完全不沾栈。
为什么必须用 Worker 做文件索引递归
文件系统结构天然递归(目录套目录),索引时需遍历所有子项。普通 JS 递归每层都压栈,几千层就爆栈;而 Worker 拥有独立调用栈,深度上限远高于主线程(通常数万层起),且不影响 UI 响应。
- 主线程执行递归:阻塞渲染、输入、动画,用户感知为“假死”
- Worker 执行递归:主线程照常滚动、点击、输入,搜索在后台静默完成
- 注意:Worker 不能读取本地文件系统(受限于浏览器沙箱),实际索引对象是前端已获取的文件树 JSON 或 IndexedDB 中的元数据
构建可递归的文件树数据结构
Worker 不支持 DOM 和 File API 直接访问,所以先要在主线程组织好纯数据结构,再传入:
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 用
structuredClone()或手动扁平化生成树形 JSON,例如:{name:"src", type:"dir", children:[{name:"index.js",type:"file",size:1200}]} - 避免循环引用、
undefined、函数——这些无法序列化,会静默丢失 - 若文件量极大(如上万节点),建议预分片:按层级或路径前缀拆成多个子任务,由多个 Worker 并行处理
Worker 内实现安全递归搜索逻辑
递归本身仍存在 Worker 自身栈溢出风险,需双重防护:
立即学习“前端免费学习笔记(深入)”;
- 优先采用尾递归写法(如
search(node, query, acc)最后一步只调自身),部分引擎可优化 - 对超深路径(如 >5000 层)自动降级为显式栈模拟(用
Array.push/pop替代函数调用) - 示例核心逻辑(worker.js):
const { tree, keyword } = e.data;
function dfs(node, path = []) {
if (node.name.includes(keyword)) {
postMessage({ match: true, path: [...path, node.name] });
}
if (node.children) {
for (const child of node.children) {
dfs(child, [...path, node.name]);
}
}
}
dfs(tree);
};
主线程调度与结果聚合
单次搜索可能返回数百条匹配路径,需合理通信避免阻塞:
- Worker 每找到一个匹配项就
postMessage一次,主线程用onmessage流式接收并追加到列表,不等全部结束 - 添加
transferable优化大数据量传输(如匹配结果含完整文件内容),用postMessage(data, [arrayBuffer]) - 搜索结束时 Worker 主动发
{ done: true }信号,主线程据此关闭 loading 状态 - 异常处理:Worker 内
try/catch捕获递归错误,主动上报{ error: "stack overflow fallback triggered" }


















