以交互方式从控制台读取值

我想用一些控制台扩展来制作一个简单的服务器http服务器。 我find了从命令行数据读取的片段。

var i = rl.createInterface(process.stdin, process.stdout, null); i.question('Write your name: ', function(answer) { console.log('Nice to meet you> ' + answer); i.close(); process.stdin.destroy(); }); 

以及反复提问,我不能简单地使用while(done){}循环? 同样,如果服务器在问题时间接收到输出,就会毁掉线路。

你不能做一个“while(done)”循环,因为这需要阻塞input,node.js不喜欢这样做。

相反,每次input内容时都要设置一个callback函数:

 var stdin = process.openStdin(); stdin.addListener("data", function(d) { // note: d is an object, and when converted to a string it will // end with a linefeed. so we (rather crudely) account for that // with toString() and then trim() console.log("you entered: [" + d.toString().trim() + "]"); }); 

我为此使用了另一个API。

 var readline = require('readline'); var rl = readline.createInterface(process.stdin, process.stdout); rl.setPrompt('guess> '); rl.prompt(); rl.on('line', function(line) { if (line === "right") rl.close(); rl.prompt(); }).on('close',function(){ process.exit(0); }); 

这允许循环提示,直到答案是right 。 它也提供了一个漂亮的小控制台。你可以find详细信息@ http://nodejs.org/api/readline.html#readline_example_tiny_cli

Readline API自12年以来已经发生了很大的变化。 文档显示了一个有用的例子来捕获来自标准stream的用户input:

 const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('What do you think of Node.js? ', (answer) => { console.log('Thank you for your valuable feedback:', answer); rl.close(); }); 

更多信息在这里。

@rob答案将在大多数时间工作,但它可能无法像你期望的那样长时间input。

这就是你应该使用的:

 const stdin = process.openStdin(); let content = ''; stdin.addListener('data', d => { content += d.toString(); }); stdin.addListener('end', () => { console.info(`Input: ${content}`); }); 

解释为什么这个解决scheme工作:

addListener('data')像缓冲区一样工作,callback将在满或/和input结束时被调用。

那么长期投入呢? 一个'data'callback将是不够的,因此它会得到你的input拆分两个或两个以上的部分。 这往往不方便。

当stdin读取器完成读取input时, addListener('end')会通知我们。 由于我们已经存储了以前的数据,现在我们可以一起阅读和处理它们。

请使用readline-sync ,这可以让您使用同步控制台而无需callback地狱。 即使使用密码:

 var favFood = read.question('What is your favorite food? ', { hideEchoBack: true // The typed text on screen is hidden by `*` (default). }); 

我相信这应该得到一个现代async-await答案,假设使用节点> = 7.x。

答案仍然使用ReadLine::question但包装它,以便while (done) {}是可能的,这是OP要求明确的。

 var cl = readln.createInterface( process.stdin, process.stdout ); var question = function(q) { return new Promise( (res, rej) => { cl.question( q, answer => { res(answer); }) }); }; 

然后是一个示例用法

 (async function main() { var answer; while ( answer != 'yes' ) { answer = await question('Are you sure? '); } console.log( 'finally you are sure!'); })(); 

导致下面的谈话

 Are you sure? no Are you sure? no Are you sure? yes finally you are sure!