You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

异步上下文数组访问问题:大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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 08:05:23