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

Node.js中fs.readFile函数未触发执行问题求助

问题

我不得不使用JavaScript,因为调用的API仅支持该语言,而我完全不了解JavaScript。我尝试编写quit函数,用于程序出错退出前存储投票列表数据,同时有init函数负责恢复数据。

我的代码如下:

function quit() {
fs.readFile(pollsName, "utf8", function readFileCallback(err, data) {
// never reach this line
    if (err) {
        console.log(err);
    } else {
        obj = JSON.parse(data); //now it an object
        obj.poll = polls.map((poll) => poll.serialize);
        json = JSON.stringify(obj); //convert it back to json
        fs.writeFile(jsonName, json, (e) => {
            if (e) throw e;
            console.log("Polls saved");
        }); // write it back
    }
});
exit(1);
}

我始终无法进入readFile()的回调逻辑。但我另有write()函数可正常向同类文件写入日志,文件名无误,目标是含"poll"空列表键的JSON文件,fs和exit模块均已通过require导入。最初尝试处理信号但因读写不安全无法实现,现打算捕获所有错误并调用该quit函数,恳请帮忙解决。

解决方案

核心原因

fs.readFile是异步操作,回调会在文件读取完成后才执行,但你在调用fs.readFile后立刻执行了exit(1),进程直接终止,回调根本没机会运行。

方法一:使用同步读写API(推荐退出场景)

同步API会阻塞直到操作完成,适合退出前的保存操作,代码简洁且无异步时序问题:

function quit() {
    try {
        // 同步读取文件
        const data = fs.readFileSync(pollsName, "utf8");
        const obj = JSON.parse(data);
        // 注意:需调用serialize方法,而非引用函数本身
        obj.poll = polls.map((poll) => poll.serialize());
        const json = JSON.stringify(obj);
        // 同步写入文件
        fs.writeFileSync(jsonName, json);
        console.log("Polls saved");
    } catch (err) {
        console.error("保存投票数据失败:", err);
    }
    // 所有操作完成后再退出
    process.exit(1);
}

方法二:异步操作完成后再退出

如果坚持用异步API,需把process.exit(1)放到最内层回调,确保读写操作完成后再退出:

function quit() {
    fs.readFile(pollsName, "utf8", function readFileCallback(err, data) {
        if (err) {
            console.error(err);
            process.exit(1);
            return;
        }
        try {
            const obj = JSON.parse(data);
            obj.poll = polls.map((poll) => poll.serialize());
            const json = JSON.stringify(obj);
            fs.writeFile(jsonName, json, (e) => {
                if (e) {
                    console.error("写入文件失败:", e);
                } else {
                    console.log("Polls saved");
                }
                // 写入完成或失败后再退出
                process.exit(1);
            });
        } catch (parseErr) {
            console.error("解析JSON失败:", parseErr);
            process.exit(1);
        }
    });
}

额外注意:原代码中obj和json是全局变量,建议用const或let声明为局部变量,避免污染全局作用域;另外poll.serialize要改成poll.serialize()才能获取序列化后的数据。

内容的提问来源于stack exchange,提问作者Noah Fraiture

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:45:34