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

使用readFile读取JSON返回消息数组却为空?求原因及解决方法

问题原因与修复方案

为什么返回空数组?

这是Node.js异步特性导致的典型问题——fs.readFile是异步非阻塞的API,代码不会等待它读取完文件再执行后续逻辑。

当你调用mensagem.getMessages()时,流程是这样的:

  1. 执行fs.readFile,发起文件读取请求,但不会等它完成
  2. 直接跳到return this._message_list,此时回调函数还没触发,_message_list还是构造函数里初始化的空数组
  3. 等文件读取完成后,回调函数才会运行,把正确值赋值给_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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:20:55