为什么节点 finish/close 在通过 process.stdin 进行流式输入时?

Why does node finish/close when streaming input via process.stdin?

我正在尝试创建一个节点应用程序,您可以通过管道输入 JSON 数据并将其作为问题显示给用户。

我在这里学习了如何绑定到 process.stdin http://dailyjs.com/2012/03/08/unix-node-pipes/

这是一个例子。以下是我在终端提问的UI

var inquirer = require("inquirer");

function runInquirer(choices) {
  inquirer.prompt([
    {
      type: "checkbox",
      message: "Select toppings",
      name: "toppings",
      choices: choices
    }
  ], function( answers ) {
    console.log( JSON.stringify(answers, null, "  ") );
  });
}

如果我直接调用处理程序,它会工作

 runInquirer([
   {name:'Cheese'},
   {name:'Tomato'}
 ]);

但是当我尝试将数据传输到其中时

  process.stdin.resume();  
  process.stdin.setEncoding('utf8');  
  process.stdin.on('data', function(data) {        
    runInquirer(JSON.parse(data));
  });

它显示问题然后立即退出。所以它不等待我的用户输入。

从命令行调用的示例(注意管道 | )

➜  test git:(master) ✗ cat questions.json | node test.js
? Select toppings (Press <space> to select)
 The usual:
 ❯◯ Peperonni
 ◉ Cheese

我也用另一个名为 https://github.com/yaronn/blessed-contrib 的节点用户界面库尝试了这个测试并得到了相同的结果。

您似乎对进程如何处理 stdin 有一点误解。 inquirer.prompt 通过使用 stdinstdout 设置提示以接受用户输入并将输出写入终端。 process.stdin.on('data', 设置一个处理程序来读取到达 stdin 的数据。当你 运行

cat questions.json | node test.js

您正在指示您的终端停止将终端用作 stdin,而是将命令 cat 的输出用作 stdin

这意味着您的两种输入方法实际上都在尝试使用相同的通道。根据您当前的结构,问题的答案也必须来自您的 questions.json 文件。它正在立即退出,因为该文件 运行 没有内容并且不可能对您的 inquirer.

有任何答案

您可能希望 test.js 文件接受 JSON 文件作为第一个参数,并读取该文件而不是从 process.stdin.[=24= 读取]