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

Ris*_*vik 145 console node.js

我想用一些控制台扩展来创建一个简单的服务器http服务器.我找到了从命令行数据中读取的代码段.

  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();

  });
Run Code Online (Sandbox Code Playgroud)

好好反复问问题,我不能简单地使用while(done) { }循环?如果服务器在提问时接收输出也很好,它会破坏该行.

rob*_*rob 172

你不能做一个"while(done)"循环,因为这需要阻塞输入,node.js不喜欢这样做.

而是设置每次输入内容时调用的回调:

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() + "]");
  });
Run Code Online (Sandbox Code Playgroud)

  • 该答案的日期为2011年,此后发生了很大变化。特别是,答案的第一部分是*您不能进行while循环... *不再成立。是的,由于async-await模式,您可以进行while循环,但仍然不会阻塞。其他答案反映了这一点。对于当今阅读此书的任何人-也请参考其他答案。 (5认同)
  • 谢谢你的工作,"结束"监听器是否允许调用一些结束操作并说'再见'? (2认同)
  • 您可以将字符串输出简化为d.toString().trim() (2认同)

Mad*_*esh 104

我为此目的使用了另一个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);
});
Run Code Online (Sandbox Code Playgroud)

这允许循环提示直到答案为止right.它也提供了很好的小控制台.你可以找到详细信息@ http://nodejs.org/api/readline.html#readline_example_tiny_cli

  • 这是一个很好的答案.可能不明显(但是是一个很大的优点)是readline不是外部依赖:它是node.js的一部分. (10认同)

Pat*_*.SE 48

自12'以来,Readline API发生了很大的变化.该文档显示了从标准流中捕获用户输入的有用示例:

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();
});
Run Code Online (Sandbox Code Playgroud)

更多信息在这里.

  • 这只是一个基本的例子.你是如何互动的?提问/回答?多种选择之类的?如何重新打开rl一旦关闭,如果不能如何使用open rl与用户交互包括一些逻辑 (5认同)

小智 23

请使用readline-sync,这样您就可以使用同步控制台而无需回调.甚至可以使用密码:

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

  • 这需要额外的依赖,所以我更喜欢其他解决方案. (5认同)

Wik*_*hla 18

我相信这值得一个现代的async-await答案,假设使用node> = 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);
        })
    });
};
Run Code Online (Sandbox Code Playgroud)

然后是一个示例用法

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

导致以下对话

Are you sure? no
Are you sure? no
Are you sure? yes
finally you are sure!
Run Code Online (Sandbox Code Playgroud)

  • 这正是我一直在寻找的答案。我觉得应该是第一名。 (3认同)
  • 美丽的。较大的脚本需要异步等待。这正是我所需要的。 (2认同)
  • @MarcusWiderberg 在脚本末尾添加 `cl.close()` 。问候。 (2认同)

zur*_*fyx 12

@rob answer大多数时候都会工作,但是它可能不会像你期望的那样长时间输入.

这就是你应该使用的:

const stdin = process.openStdin();
let content = '';

stdin.addListener('data', d => {
  content += d.toString();
});

stdin.addListener('end', () => {
  console.info(`Input: ${content}`);
});
Run Code Online (Sandbox Code Playgroud)

解释为什么此解决方案有效:

addListener('data') 就像一个缓冲区,回调将在它满或/和它的输入结束时被调用.

长输入怎么样?单个'data'回调是不够的,因此您将在两个或更多部分中分配输入.这通常不方便.

addListener('end')当stdin阅读器完成阅读我们的输入后会通知我们.由于我们一直存储以前的数据,现在我们可以一起阅读和处理它们.

  • 当我使用上面的代码并插入一些输入,然后"输入"键控制台不断询问我更多的输入.我们如何终止它? (3认同)

Dio*_*oso 5

我建议使用Inquirer,因为它提供了常见的交互式命令行用户界面的集合。

const inquirer = require('inquirer');

const questions = [{
  type: 'input',
  name: 'name',
  message: "What's your name?",
}];

const answers = await inquirer.prompt(questions);
console.log(answers);
Run Code Online (Sandbox Code Playgroud)


Mig*_*ota 5

这是一个例子:

const stdin = process.openStdin()

process.stdout.write('Enter name: ')

stdin.addListener('data', text => {
  const name = text.toString().trim()
  console.log('Your name is: ' + name)

  stdin.pause() // stop reading
})
Run Code Online (Sandbox Code Playgroud)

输出:

Enter name: bob
Your name is: bob
Run Code Online (Sandbox Code Playgroud)