等待用户在Node.js中inputinput

我理解Node.js中asynchronous事件的基本原理,我正在学习如何编写代码。 但是,我坚持以下情况:

我想编写代码偶尔暂停用户input。

该程序不是作为服务器(尽pipe目前它的目的是为命令行)。 我意识到这是Node的非典型使用。 我的目标是最终将程序迁移回客户端的Javascript应用程序,但我发现在Node.js中工作既迷人又非常有用的debugging。 这让我回到我的例子来说明问题:

它读入一个文本文件并输出每行,除非行以“?”结尾。 在这种情况下,用户应该暂停以澄清该行的含义。 目前我的程序首先输出所有行,最后等待澄清。

有没有什么办法强制node.js暂停命令行input的情况下,精确的情况下,有条件的火灾(即行的地方以“?”结束?

var fs = require("fs"); var filename = ""; var i = 0; var lines = []; // modeled on http://st-on-it.blogspot.com/2011/05/how-to-read-user-input-with-nodejs.html var query = function(text, callback) { process.stdin.resume(); process.stdout.write("Please clarify what was meant by: " + text); process.stdin.once("data", function(data) { callback(data.toString().trim()); }); }; if (process.argv.length > 2) { filename = process.argv[2]; fs.readFile(filename, "ascii", function(err, data) { if (err) { console.error("" + err); process.exit(1); } lines = data.split("\n"); for (i = 0; i < lines.length; i++) { if (/\?$/.test(lines[i])) { // ask user for clarification query(lines[i], function(response) { console.log(response); process.stdin.pause(); }); } else { console.log(lines[i]); } } }); } else { console.error("File name must be supplied on command line."); process.exit(1); } 

诀窍是不做迭代,但recursion地做for循环。 因此,下一行是printOut在callback中,这被称为A:在行被打印之后,或者B:在控制台input被处理之后。

 var fs = require("fs"); // modeled on http://st-on-it.blogspot.com/2011/05/how-to-read-user-input-with-nodejs.html function query(text, callback) { 'use strict'; process.stdin.resume(); process.stdout.write("Please clarify what was meant by: " + text); process.stdin.once("data", function (data) { callback(data.toString().trim()); }); } function printLinesWaitForQuestions(lines, someCallbackFunction) { 'use strict'; function continueProcessing() { if (lines.length) { printNextLine(lines.pop()); } else { someCallbackFunction(); } } function printNextLine(line) { if (/\?$/.test(line)) { // ask user for clarification query(line, function (response) { console.log(response); process.stdin.pause(); continueProcessing(); }); } else { console.log(line); continueProcessing(); } } continueProcessing(); } if (process.argv.length > 2) { var filename = process.argv[2]; fs.readFile(filename, "ascii", function (err, data) { 'use strict'; if (err) { console.error("" + err); process.exit(1); } var lines = data.split("\n"); printLinesWaitForQuestions(lines, function () { console.log('Were done now'); }); }); } else { console.error("File name must be supplied on command line."); process.exit(1); } 

这是一个很好的解决scheme,有两个原因:

  1. 它相对干净,整个过程可以包含在自己的function封闭中,有可能导致模块化。

  2. 它不会破坏你可能想要做的其他asynchronous事情。

    没有迭代等待循环,只有一个asynchronous任务被启动每行你有。 如果在你的版本中,你有几百万行? 你会立即抛出数以百万计的asynchronous输出…不好的!

    recursion方法不仅允许您希望执行的其他asynchronous工作的并发性更好,而且不会因一个函数调用中的迷你asynchronous任务而阻塞事件循环。 这可能会导致内存问题,性能下降以及其他值得避免的问题,特别是在大型input上。

我发现了一个很容易就可以做到的模块:

https://www.npmjs.com/package/cli-interact

安装: npm install cli-interact --save-dev

如何使用直接从npm站点取得:

 var query = require('cli-interact').getYesNo; var answer = query('Is it true'); console.log('you answered:', answer);