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

Node.js读取JSON文件的另一种方式及fs.readFile返回问题咨询

解决方案:异步读取JSON文件并返回数据

你遇到的问题核心在于fs.readFile是异步非阻塞的API——它不会等待文件读取完成再往下执行,而是直接继续运行后续代码,等到文件读取完成后才会调用传入的回调函数。这就导致你的loadTableSS函数在回调里的数组还没生成时就已经返回了,自然拿不到数据。

下面给你两种适配现有代码的解决方案:

方案一:使用同步读取方法 fs.readFileSync

如果你的JSON文件体积不大,同步读取是最简单的替代方案,它会阻塞线程直到文件读取完成,这样就能直接拿到数据并处理:

修改你的ReportsController代码:

const fs = require('fs');
const path = require('path'); // 用path模块处理路径更可靠

module.exports = {
  loadTableSS: function (payload) {
    // 用path.resolve生成绝对路径,避免相对路径问题
    const filePath = path.resolve(__dirname, '../app/JSONFiles/customerSatisfaction.json');
    // 同步读取并解析JSON
    const saborServicioJSON = JSON.parse(fs.readFileSync(filePath, 'utf8'));

    const sucursales = JSON.parse(payload.payload.Sucursales);
    const selectedweek = payload.payload.SelectedWeek;
    const selectedyear = payload.payload.SelectedYear;
    const arrayTable = [];

    for (let i = 0; i < sucursales.length; i++) {
      const sucursal = sucursales[i].toString();
      // 改用原生数组forEach遍历,替代jQuery的each方法,减少依赖
      saborServicioJSON.forEach(item => {
        const datadate = new Date(item.date);
        const datayear = datadate.getFullYear();
        if (item.storeID === sucursal && item.week === selectedweek && datayear === selectedyear) {
          arrayTable.push(item);
        }
      });
    }
    return arrayTable;
  }
}

路由代码可以保持不变,因为同步读取的函数还是同步返回数据。

方案二:用Promise + Async/Await 处理异步读取

如果需要保持异步非阻塞(比如文件较大或不想阻塞事件循环),推荐用Promise封装文件读取,再配合async/await让代码逻辑更清晰:

首先修改ReportsController:

const fs = require('fs').promises; // 使用fs的Promise版本,避免手动封装回调
const path = require('path');

// 封装异步读取JSON的复用函数
async function readSaborServicioJSON() {
  const filePath = path.resolve(__dirname, '../app/JSONFiles/customerSatisfaction.json');
  const data = await fs.readFile(filePath, 'utf8');
  return JSON.parse(data);
}

module.exports = {
  // 把loadTableSS改成async函数
  loadTableSS: async function (payload) {
    const saborServicioJSON = await readSaborServicioJSON();

    const sucursales = JSON.parse(payload.payload.Sucursales);
    const selectedweek = payload.payload.SelectedWeek;
    const selectedyear = payload.payload.SelectedYear;
    const arrayTable = [];

    for (let i = 0; i < sucursales.length; i++) {
      const sucursal = sucursales[i].toString();
      saborServicioJSON.forEach(item => {
        const datadate = new Date(item.date);
        const datayear = datadate.getFullYear();
        if (item.storeID === sucursal && item.week === selectedweek && datayear === selectedyear) {
          arrayTable.push(item);
        }
      });
    }
    return arrayTable;
  }
}

然后修改路由文件,因为handler现在要处理异步函数,需要改成async函数:

const reportsController = require('../private_modules/ReportsController')
server.route({
  method: 'POST',
  path: '/ssLoadTable',
  handler: async function (request, reply) {
    // 用await等待异步函数返回结果
    const tableData = await reportsController.loadTableSS(request);
    reply(tableData);
  }
});

内容的提问来源于stack exchange,提问作者Danitza Ayala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 03:43:20