【问题标题】:Process never ends when using 'process.stdin.once'使用“process.stdin.once”时,进程永远不会结束
【发布时间】:2019-06-08 12:19:01
【问题描述】:

在我的节点脚本中,我正在等待用户在某个时候按下回车键:

console.log("Press enter to continue...");
await new Promise(function(resolve, reject) {
    process.stdin.once("data", function(data) {
        resolve();
    });
});

脚本运行良好,只有在用户按下回车后才会继续运行。

但在执行结束时,进程并没有终止。

相反,它似乎只是等待用户输入(即,每次按 Enter 时都会打印一个换行符)。

我很确定问题与process.stdin.once 有关,而不是我如何使用Promise 来强制同步执行。

我的脚本中有几个地方我必须等待用户按 Enter,因此在解决承诺之前添加 process.stdin.end() 是不可能的(这意味着等待用户按 Enter 将起作用只有一次)。

我该如何解决这个问题?

【问题讨论】:

  • 这不可能是你的全部代码,因为await 只能在async 函数中使用。
  • @Pointy:当然这不是我的全部代码。我已经明确地说明了这一点(“我的脚本做这个和那个......”)。是的 - 这个 sn-p 确实是从 async 函数调用的。
  • 好吧,人们永远不知道这里隐藏着什么可能隐藏在未发布的代码中。也就是说,给定的答案是正确的,尽管在 UNIX/Linux C 代码中惯用,您可能只是明确地 exit() 或退出 main 函数(我意识到 Node 程序中不存在该函数)。跨度>
  • @Pointy:从技术上讲,因为我确实知道我的脚本在哪里开始和结束(查看所有异步调用),所以我只是在开头添加了process.stdin.resume(),最后添加了process.stdin.pause()。其余的都保持不变。谢谢。

标签: javascript node.js process user-input stdin


【解决方案1】:

这是因为只要您的标准输入流打开,节点就会假定您可能正在等待更多数据。以任何方式读取流后,流会自动打开。通知节点您不再需要更多输入的一种简单方法是调用pause()。这是一个简单的例子:

async function example() {
    console.log("Step 1");
    await new Promise(function(resolve, reject) {
        process.stdin.once("data", function(data) {
            resolve();
        });
    });

    console.log("Step 2");
    await new Promise(function(resolve, reject) {
        process.stdin.once("data", function(data) {
            resolve();
        });
    });

    // more steps...
}

example().then(() => {
    console.log("Done");
    process.stdin.pause();
});

【讨论】:

  • 所以我可以在resolve() 之前拨打process.stdin.pause() 吗?
  • 有点——如果你这样做了,你必须确保你也 resume() 在你尝试再次收集用户输入之前。在已经恢复的流上调用resume() 是安全的,pause() 也是如此,所以如果你想将“等待用户输入”逻辑包装到一个小辅助函数中,你应该首先调用resume(),然后设置您的once 处理程序,然后在返回之前设置pause()
猜你喜欢
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2013-04-09
  • 2010-12-27
  • 1970-01-01
  • 2021-08-05
相关资源
最近更新 更多