Node.js 9.4及更早版本中如何同步readline输入?
解决Node.js readline异步执行导致变量未赋值的问题
你遇到的问题本质是readline的question()方法是异步非阻塞的——它会立即返回,不会等待用户输入完成就继续执行后面的console.log(x),这时候x还没被回调函数赋值,所以输出undefined。
针对Node.js 9.4或更早版本,这里有几种可靠的解决方案:
方法1:将后续代码放入回调函数(最直接)
最简单的方式就是把需要使用输入值的代码直接写在question()的回调函数里,确保它在输入完成后才执行:
const readline = require('readline'); function createReadObject() { read = readline.createInterface({ input: process.stdin, output: process.stdout }); } var x; var read; createReadObject(); read.question("input :",(input) => { x = input; read.close(); // 所有需要使用x的代码都放在这里 console.log(x); // 现在能正确输出输入的值 });
方法2:用Promise封装+async/await(代码更清晰)
Node.js 8及以上版本已经支持async/await,9.4完全兼容。我们可以把question()包装成Promise,用同步风格的代码处理异步流程:
const readline = require('readline'); // 封装readline的提问逻辑为Promise function askQuestion(prompt) { const read = readline.createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { read.question(prompt, (input) => { read.close(); resolve(input); // 将输入值传递出去 }); }); } // 使用async函数来await异步结果 async function main() { const x = await askQuestion("input :"); console.log(x); // 这里会等待输入完成后再执行 // 后续所有需要使用x的代码都可以写在这里 } // 执行主函数 main();
这种方式在需要多个连续输入的场景下优势明显,代码结构会比嵌套回调更整洁。
方法3:使用Promise的then()方法(替代async/await)
如果你不想用async/await,也可以直接用Promise的then()链式调用:
const readline = require('readline'); function askQuestion(prompt) { const read = readline.createInterface({ input: process.stdin, output: process.stdout }); return new Promise((resolve) => { read.question(prompt, (input) => { read.close(); resolve(input); }); }); } askQuestion("input :") .then((x) => { console.log(x); // 后续代码放在then回调里 });
核心思路就是让依赖输入值的代码等待异步输入操作完成,以上三种方法都能解决你的问题,根据场景选择即可。
内容的提问来源于stack exchange,提问作者Aman Ullah
相关产品推荐
相关产品推荐

