0
0

More than 3 years have passed since last update.

Node.js の beforeExit で非同期処理を書くと終わらなくなる

Last updated at Posted at 2020-07-24

Node.js で終了時のクリーンアップ処理を書こうとすると、 exit イベントか beforeExit イベントの2択になる。 exit だと非同期処理が書けないので、事実上 beforeExit の1択…と思って使ってみたらちょっとだけハマったのでメモ。

process.on('beforeExit', (code) => {
  console.log('Delayed');
  setTimeout(() => {
    console.log('Process beforeExit event with code: ', code);
  }, 1000);
});

process.on('exit', (code) => {
  console.log('Process exit event with code: ', code);
});

console.log('This message is displayed first.');

こんな感じの検証コードを書いて実行したら、 beforeExit の部分がこんな感じで延々実行されて止まらなくなった。

This message is displayed first.
Delayed
(1秒ウェイト)
Process beforeExit event with code:  0
Delayed
(1秒ウェイト)
Process beforeExit event with code:  0
Delayed
(1秒ウェイト)
Process beforeExit event with code:  0
Delayed
(1秒ウェイト)
...

どうも beforeExit の中で非同期処理を書くと、そこで「イベントループが空ではなくなった」ということで beforeExit 発火前の状態に戻ってしまうらしい。ぐぬぬ。

仕方ないので、1回だけしか実行されないようにガードしてみた。

let isBeforeExitAlreadyFired = false;

process.on('beforeExit', (code) => {
  // beforeExit を1回しか実行させないためのガード条件
  if (isBeforeExitAlreadyFired) {
    return;
  }
  isBeforeExitAlreadyFired = true;

  console.log('Delayed');
  setTimeout(() => {
    console.log('Process beforeExit event with code: ', code);
  }, 1000);
});

process.on('exit', (code) => {
  console.log('Process exit event with code: ', code);
});

console.log('This message is displayed first.');
This message is displayed first.
Delayed
Process beforeExit event with code:  0
Process exit event with code:  0

めでたしめでたし。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0