Erel Segal-Halevi
Erel Segal-Halevi

Reputation: 36715

How does catching Ctrl-C works in Node?

I have the following program in Node.js on Ubuntu:

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

while(1) {

}

When I click Ctrl+C, I see "^C" on the screen, but nothing else is printed the process doesn't exit.

Without the "process.on..." statement, Ctrl+C immediately causes Node to exit.

What am I doing wrong?

Upvotes: 6

Views: 4472

Answers (1)

Iolo
Iolo

Reputation: 2232

As said above, the issue is that your while loop never yields and is blocking the event loop. If you need to make use of a while loop then making the loop part of an async function with at least 1 await call would resolve this issue:

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

Since async/await is syntactic sugar over Promises and not all environments support async/await, you could also do this directly with Promises if you are in a less modern environment, but the code would be much different:

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

Lastly, if you aren't using an environment with Promises there's also just replacing the while loop with an interval:

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

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

Upvotes: 4

Related Questions