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

Node.js中异步读取JSON文件转对象时数据为空的解决方法

解决Node.js异步遍历JSON文件并等待所有操作完成的问题

你的代码核心问题出在异步操作的控制上——还没等所有文件读取解析完成,同步代码就提前执行了,而且forEach循环也没正确等待每个异步任务结束。我来一步步帮你修复:

原代码的关键问题

  • forEach不支持async/await:files.forEach(async file => { ... })里的async函数不会被forEach等待,循环会直接跑完,所有文件读取操作还在后台进行时,后续代码已经执行了。
  • fs.readFile的错误用法:你混用了回调和await,回调版本的fs.readFile不返回Promise,await对它完全无效;而且回调里的data参数覆盖了外部的data数组,根本没把解析后的对象push进去。
  • 同步代码提前执行:console.log(data)是同步逻辑,在所有异步操作完成前就运行了,自然输出空数组。

优化后的解决方案

我们可以用Node.js内置的fs.promises(Node.js 10+支持)简化异步操作,结合Promise.all等待所有文件处理完成,代码更清晰可靠:

const fs = require('fs').promises;
const path = require('path'); // 用path模块处理路径更安全,避免跨平台问题

// 封装成一个async函数,统一处理所有逻辑
async function getAllJsonData(dataFolder) {
  try {
    // 1. 读取目标目录下的所有文件
    const files = await fs.readdir(dataFolder);
    
    // 2. 为每个文件生成"读取+解析JSON"的Promise
    const jsonProcessingPromises = files.map(async (fileName) => {
      // 用path.join拼接路径,比手动拼字符串更可靠
      const fullFilePath = path.join(__dirname, 'parsed_json_data', fileName);
      // 读取文件内容(fs.promises.readFile返回Promise,可直接await)
      const fileContent = await fs.readFile(fullFilePath, 'utf8');
      // 解析JSON并返回,结果会被Promise.all收集
      return JSON.parse(fileContent);
    });
    
    // 3. 等待所有Promise完成,拿到所有解析后的JSON对象数组
    const allParsedData = await Promise.all(jsonProcessingPromises);
    
    return allParsedData;
  } catch (error) {
    console.error('处理JSON文件时出错:', error);
    throw error; // 抛出错误让调用方可以处理
  }
}

// 使用这个函数
getAllJsonData(dataFolder)
  .then((finalData) => {
    console.log(finalData); // 这里就能拿到所有解析后的JSON数据了
    // 在这里继续处理你的数据
  })
  .catch((err) => {
    console.error('获取JSON数据失败:', err);
  });

关键优化点说明

  1. 使用fs.promises:替代回调式的fs方法,直接用async/await处理异步操作,代码更简洁易读,不需要手动封装Promise。
  2. path.join处理路径:避免手动拼接路径时出现的斜杠问题,适配Windows、Linux等不同操作系统。
  3. Promise.all等待所有异步任务:files.map生成一个Promise数组,每个Promise对应一个文件的读取和解析,Promise.all会等待所有Promise都resolve后,返回包含所有结果的数组,保证所有文件都处理完再继续。
  4. 统一错误处理:用try/catch包裹所有异步操作,集中处理错误,比分散的错误处理更清晰。

兼容旧版本Node.js(低于10)的方案

如果你的Node.js版本不支持fs.promises,可以用util.promisify把回调式方法转换成Promise版本:

const fs = require('fs');
const util = require('util');
const path = require('path');

// 把回调式方法转换成Promise版本
const readdir = util.promisify(fs.readdir);
const readFile = util.promisify(fs.readFile);

async function getAllJsonData(dataFolder) {
  try {
    const files = await readdir(dataFolder);
    const jsonProcessingPromises = files.map(async (fileName) => {
      const fullFilePath = path.join(__dirname, 'parsed_json_data', fileName);
      const fileContent = await readFile(fullFilePath, 'utf8');
      return JSON.parse(fileContent);
    });
    return await Promise.all(jsonProcessingPromises);
  } catch (error) {
    console.error('处理出错:', error);
    throw error;
  }
}

// 使用方式和之前一致
getAllJsonData(dataFolder)
  .then(data => console.log(data))
  .catch(err => console.error(err));

内容的提问来源于stack exchange,提问作者Kristoffer Tølbøll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:41:25