使用readFile读取JSON返回消息数组却为空?求原因及解决方法
问题原因与修复方案
为什么返回空数组?
这是Node.js异步特性导致的典型问题——fs.readFile是异步非阻塞的API,代码不会等待它读取完文件再执行后续逻辑。
当你调用mensagem.getMessages()时,流程是这样的:
- 执行
fs.readFile,发起文件读取请求,但不会等它完成 - 直接跳到
return this._message_list,此时回调函数还没触发,_message_list还是构造函数里初始化的空数组 - 等文件读取完成后,回调函数才会运行,把正确值赋值给
_message_list并打印,但这时候return早就执行完了,所以你拿到的是空数组
几种可行的修复方案
方案1:使用Promise + async/await(推荐,现代JS写法)
我们可以把fs.readFile包装成Promise,再用async/await让代码看起来像同步一样,同时保留异步的性能优势。
修改后的Message类:
var fs = require("fs"); const { promisify } = require("util"); // 把异步的readFile转成Promise版本 const readFileAsync = promisify(fs.readFile); class Message { constructor() { this._message_list = []; } set message_list(val) { this._message_list = val; } get message_list() { return this._message_list; } // 把方法标记为async async getMessages() { try { // 等待文件读取完成 const data = await readFileAsync("./models/messages-list.json", "utf8"); this._message_list = Object.keys(JSON.parse(data)); console.log(this._message_list); return this._message_list; } catch (err) { console.error("读取文件失败:", err); return []; // 出错时返回空数组,也可以抛出错误让调用方处理 } } } module.exports = { Message };
调用的时候,因为getMessages是async函数,需要用await获取结果:
var { Message } = require("./models/message"); // 必须在async函数里使用await async function init() { const mensagem = new Message(); const messages = await mensagem.getMessages(); console.log(messages); // 现在会正确输出["message 1", "message 2"] } init();
方案2:同步读取文件(仅适合简单脚本)
如果你的代码是一次性脚本,不需要处理高并发,可以用fs.readFileSync同步读取,它会阻塞代码直到文件读取完成:
修改getMessages方法:
getMessages() { try { const data = fs.readFileSync("./models/messages-list.json", "utf8"); this._message_list = Object.keys(JSON.parse(data)); console.log(this._message_list); return this._message_list; } catch (err) { console.error("读取文件失败:", err); return []; } }
调用时直接用:
var { Message } = require("./models/message"); const mensagem = new Message(); console.log(mensagem.getMessages()); // 直接得到正确数组
⚠️ 注意:同步读取会阻塞Node.js的事件循环,如果是Web服务器这类需要处理大量请求的应用,绝对不要用,会导致性能急剧下降。
方案3:传统回调函数方式
如果你习惯回调风格,也可以给getMessages传入回调,在读取完成后返回结果:
修改getMessages:
getMessages(callback) { fs.readFile("./models/messages-list.json", "utf8", (err, data) => { if (err) { callback(err, null); return; } this._message_list = Object.keys(JSON.parse(data)); console.log(this._message_list); callback(null, this._message_list); }); }
调用时:
var { Message } = require("./models/message"); const mensagem = new Message(); mensagem.getMessages((err, messages) => { if (err) { console.error("读取失败:", err); return; } console.log(messages); // 正确输出数组 });
内容的提问来源于stack exchange,提问作者csassis
相关产品推荐
相关产品推荐

