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
相关产品推荐
相关产品推荐

