【问题标题】:How does catching Ctrl-C works in Node?在 Node 中捕捉 Ctrl-C 是如何工作的?
【发布时间】:2014-03-23 17:54:20
【问题描述】:

我在 Ubuntu 上的 Node.js 中有以下程序:

process.on ("SIGINT", function(){
    console.log("You clicked Ctrl+C!");
    process.exit(1);
});

while(1) {

}

当我单击 Ctrl+C 时,我在屏幕上看到“^C”,但没有打印任何其他内容,进程不会退出。

如果没有“process.on...”语句,Ctrl+C 会立即导致 Node 退出。

我做错了什么?

【问题讨论】:

  • 我相信,由于你的 while(1) 循环永远不会产生,事件循环没有轮到处理 control-C。否则,您正在做的事情看起来应该可以工作。
  • 嗯。我可以试着回答这个问题——你对什么信号有多熟悉?与“C 代码”(又名,直接添加带有 sigaction 或信号的信号处理程序)不同 - 在 Node 中,它们不会导致程序突然运行其他代码。相反,它们由节点处理并“移交”给事件循环。由于 Node 运行 JavaScript 单线程(通常)并且您永远不会产生控制权 - 事件处理程序永远不会被调用,因为繁忙的等待会使其死锁(同样,一次只运行一件事)。在 Node 中,您必须从不阻塞事件循环。

标签: node.js events signals sigint


【解决方案1】:

如上所述,问题在于您的while 循环永远不会产生并阻塞event loop。如果您需要使用 while 循环,那么使用至少 1 个 await 调用将循环作为 async 函数的一部分将解决此问题:

const pause = () => new Promise(res => setTimeout(res, 0));

process.on ('SIGINT',() => {
  console.log('You clicked Ctrl+C!');
  process.exit(1);
});

(async function() {

  while(true) {
    console.log('Running Code');
    await pause();
  }
})();

由于 async/await 是 Promises 的语法糖,并且并非所有环境都支持 async/await,因此如果您处于不太现代的环境中,您也可以直接使用 Promises 执行此操作,但代码会大不相同:

const pause = () => new Promise(res => setTimeout(res, 0));

process.on ('SIGINT',() => {
  console.log('You clicked Ctrl+C!');
  process.exit(1);
});

const main = () => new Promise(() => {
  // do stuff
  console.log('Running Code');
});

function loop(task) {
  task();
  return pause().then(() => {
    task();
    return loop(task);
  });
}

loop(main);

最后,如果您没有使用带有 Promises 的环境,也只需将 while 循环替换为间隔:

process.on ('SIGINT',() => {
  console.log('You clicked Ctrl+C!');
  process.exit(1);
});

setInterval(() => {
  console.log('Running Code');
}, 0)

【讨论】:

    猜你喜欢
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    相关资源
    最近更新 更多