Node.js如何将stdin采集的用户输入正常写入JSON文件
问题根因拆解
- 全链路执行时序错位:Node.js 基于事件循环的异步IO模型决定了
fs.readFile、process.stdin都是非阻塞的异步流程,你当前的代码启动后会并行跑两个完全独立的分支:- 立刻触发jsonReader读取db.json,拿到文件内容后硬编码写回,全程不会等待用户输入
- 立刻抛出第一个收集问题,等用户逐行输入完所有答案后直接退出进程,完全没有触发把输入值写入JSON的逻辑
- 序列化特性导致字段丢失:如果你把赋值语句改成
customer.Token = answers[1],因为jsonReader的回调执行时用户还没开始输入,answers数组还是空值,取到的answers[1]为undefined;而JSON.stringify的原生规则是,对象中值为undefined的属性会在序列化时被直接丢弃,最终写入文件时Token字段自然就消失了。 - 无效的对象引用:代码开头
const customer = require('./db.json')拿到的是Node模块加载阶段就缓存的JSON对象,和后续jsonReader从磁盘读取出来的对象是两个完全独立的引用,后续对这个缓存对象的修改根本不会影响实际的文件读写流程。
为什么之前硬编码赋值(比如
customer.Token = "Hi")能正常写入?因为硬编码的值是固定有效字符串,不存在依赖异步流程取值的问题,哪怕时序错位,序列化时也会正常写入字段,不会出现丢失情况。
修正后符合需求的实现逻辑
必须等所有用户输入全部收集完成后,再去读取磁盘上的db.json,将用户的回答和原有字段合并后再写回,完整可运行代码如下:
const fs = require("fs"); const DB_PATH = "./db.json"; // 预设控制台提问 const questions = [ 'Cual es tu nombre?' , 'Cual es tu Token?' , 'Cual es tu numero de orden?' ]; const collectedAnswers = []; // 封装JSON文件读取方法 function readDbFile(path, callback) { fs.readFile(path, (err, rawData) => { if (err) return callback(err); try { return callback(null, JSON.parse(rawData)); } catch (parseErr) { return callback(parseErr); } }); } // 抛出当前待回答的问题 function triggerQuestion(index) { process.stdout.write(`${questions[index]}: `); } // 监听控制台用户输入 process.stdin.on('data', (inputBuffer) => { const cleanInput = inputBuffer.toString().trim(); collectedAnswers.push(cleanInput); if (collectedAnswers.length < questions.length) { // 未收集完所有回答,抛出下一个问题 triggerQuestion(collectedAnswers.length); return; } // 全部回答收集完成,开始读写JSON文件 readDbFile(DB_PATH, (err, dbContent) => { if (err) { console.error("读取db.json失败:", err); process.exit(1); } // 将用户输入对应映射到JSON字段 dbContent.name = collectedAnswers[0]; dbContent.Token = collectedAnswers[1]; dbContent.order_count = collectedAnswers[2]; // 格式化写回文件 fs.writeFile(DB_PATH, JSON.stringify(dbContent, null, 2), (writeErr) => { if (writeErr) { console.error("写入db.json失败:", writeErr); process.exit(1); } console.log("所有回答已成功保存"); process.exit(0); }); }); }); // 启动第一个问题 triggerQuestion(0);
内容的提问来源于stack exchange,提问作者Jabibi
相关产品推荐
相关产品推荐

