以交互方式从控制台读取值
我想用一些控制台扩展来制作一个简单的服务器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!