异步上下文数组访问问题:大JSON文件读取后列表为空
解决Node.js异步流处理后全局变量无法获取数据的问题
你的代码里list最后为空,核心问题是错误混用了回调、异步函数和流的事件机制,导致代码执行顺序完全不符合预期:
fs.readdir的回调版本不返回Promise,await对它完全无效,代码会直接跳到console.log那一行forEach不支持异步遍历,await files.forEach(...)不会等待所有文件的流处理完成- 流的
on('data')是事件监听,await在这里起不到等待作用,流的处理是异步的,还没触发data事件,console.log就已经执行了
下面是修正后的代码,用Promise化的API和Promise.all来确保所有异步操作完成后再访问list:
const list: HostInfo[] = []; (async () => { // 使用fs.promises.readdir替代回调版本,支持await const files = await fs.promises.readdir(JSON_DIR); // 用map+Promise.all处理所有文件的异步操作,等待全部完成 await Promise.all(files.map(async filename => { return new Promise<void>((resolve, reject) => { const readStream = fs.createReadStream(path.join("output/scheduled", filename)); const parseStream = json.createParseStream(); // 监听data事件收集数据 parseStream.on('data', (hostlist: HostInfo[]) => { // 这里不需要async,直接push就行 hostlist.forEach(host => { list.push(host); }); }); // 监听end事件,标记当前文件处理完成 parseStream.on('end', () => { resolve(); }); // 监听错误事件,处理异常 parseStream.on('error', (err) => { reject(err); }); readStream.pipe(parseStream); }); })); // 现在所有文件的流都处理完成了,list里有数据 console.log(list.length); })();
关键改动点:
- 改用
fs.promises.readdir,确保等待目录读取完成再处理文件 - 每个文件的流处理封装成Promise,通过监听
end和error事件来控制Promise的状态 - 用
Promise.all包裹所有文件的Promise,确保所有文件处理完成后才执行后续代码 - 去掉了不必要的
async嵌套,data事件回调里不需要异步操作,直接push即可
内容的提问来源于stack exchange,提问作者Mice Nic
相关产品推荐
相关产品推荐

