2017-03-08 5 views
0

https://nodejs.org/api/process.html`exit`イベントは、手動

にリスナー関数のみ同期操作を実行しなければならないとは異なる挙動します。 Node.jsプロセスは、 'exit'イベント リスナーを呼び出した直後に終了し、イベントループ に依然としてキューイングされている追加の作業が放棄されます。次の例では、例えば、タイムアウト が発生することはありません:

process.on('exit', (code) => { 
    setTimeout(() => { 
    console.log('This will not run'); 
    }, 0); 
}); 

今、私は私のmain.jsでこれを持っている:シャットダウン・リスナーなどのIを持っているロガーで

if (errors) { 
    process.exitCode = 1; 
} 
process.emit("exit"); 

Mongoの接続を持っていると、次の

process.on("exit", (code) => { 
     if (this.status.finishedAt === null) { 
      this.status.currentState = StatusUpdater.STATE_STOPPED; 
      this.status.finishedAt = new Date(); 
      this.persistStatus() 
      .then(() => { 
       this.mongoDb.close().then(() => { 
        setTimeout(() => { 
         console.log('byebye'); 
         process.exit(code); 
        }, 5000); 
       }); 
      }) 
      .catch(this.noMongoConnection); 
     } 
    }); 

出力は次のとおりです。byebye秒後210秒

今私は混乱しています。明らかに、exitイベントがトリガーされた後、私は非同期操作を行うことができます。マニュアルでは、これは不可能だと言います。

何が正しく、何が間違っていますか?

+0

'exit'イベントハンドラの中で' process.exit(code);を呼び出すのは非常に奇妙です。私はこれが実際にすべてのハンドラーを2回トリガーするかどうか疑問に思います。 – Bergi

+0

@Bergiしているので、 'finishedAt'が未定義でないかチェックします。また、 'SIGINT'をトリガーすると、' exit'イベントも後で呼び出されます。 – DanFromGermany

+0

@Bergiシャットダウンハンドラのアイデアはありますか?私の解決策の唯一の欠点は、別の出口リスナーが存在し、他のリスナーの前に 'process.exit()'を実行したときに実行されない可能性があることです。 – DanFromGermany

答えて

1

名前がexitのイベントを手動で送信しているため、特別な動作が発生しないためです。 process.exit

if (errors) 
    process.exit(1); 

のように使用した場合のみ、ドキュメントに記載されている効果があります。

+0

'.exit()'を呼び出すことと 'exit'イベントを出すことの違いはドキュメントでは明確になるはずですが、答えが同じではないことを理解するのに役立ちます。 – DanFromGermany

関連する問題