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回だけしか実行されないようにガードしてみた。
letisBeforeExitAlreadyFired=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
めでたしめでたし。
参考
- Node.js Documentation
- Process on beforeExit doesn't work correctly?ここを見る限り、この
beforeExit
の振る舞いは v0.x の頃から変わっていないらしい。あまり使われていないのだろうか…。