2016-11-13 70 views
6

在我的進程終止之前,我一直試圖執行異步操作。如何在退出時執行異步操作

說 '終止' 我的意思是終端的每一種可能性:

  • ctrl+c
  • 未捕獲的異常
  • 崩潰的代碼
  • 任何
  • 結束..

要我的知識exit事件不過是用於同步操作。

讀取文檔的NodeJS我發現beforeExit事件是異步操作,但:

的「beforeExit」事件不會對發射造成條件顯式的終止,如調用process.exit()或捕獲的異常。

'beforeExit'不應該被用來作爲'退出'事件的替代,除非意圖是安排額外的工作。

有什麼建議嗎?

+1

如何把所有的代碼放在不同的文件中(例如afterExit.js),當退出事件發生時,然後運行require('child_process')。exec('node afterExit.js');',這只是一想到雖然 – Molda

+0

@Molda嘿再次,我離開了這個問題一段時間,現在回到工作,想通過使用和外部腳本來執行像你所建議的將是一個簡單的解決方案,但我來了一個錯誤的理解如何通過任何該腳本的變量,因爲'afterExit'代碼取決於父母的狀態,任何幫助將不勝感激! –

+0

您可以傳遞一些變量,例如params。 exec('node afterExit.js some_param some_other_param');'然後用'process.args'訪問,或者用所需的數據創建一個json文件,並將該文件的路徑傳遞給腳本並從afterExit加載該文件。js – Molda

回答

4

在退出之前,您可以捕獲信號並執行異步任務。像這樣的東西會調用終止()函數退出(代碼甚至JavaScript錯誤)前:

process.on('exit', function() { 
    // Do some cleanup such as close db 
    if (db) { 
     db.close(); 
    } 
}); 

// catching signals and do something before exit 
['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 
    'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM' 
].forEach(function (sig) { 
    process.on(sig, function() { 
     terminator(sig); 
     console.log('signal: ' + sig); 
    }); 
}); 

function terminator(sig) { 
    if (typeof sig === "string") { 
     // call your async task here and then call process.exit() after async task is done 
     myAsyncTaskBeforeExit(function() { 
      console.log('Received %s - terminating server app ...', sig); 
      process.exit(1); 
     }); 
    } 
    console.log('Node server stopped.'); 
} 

添加的評論請求細節:

  • 信號從節點的documentation解釋說,這個鏈接是指標準POSIX signal names
  • 信號應該是字符串。但是,我看到其他人已經完成了檢查,所以可能會有一些我不知道的其他意外信號。只需要在調用process.exit()之前確定。無論如何,我認爲這並不需要太多時間來做檢查。
  • for db.close(),我想這取決於你使用的驅動程序。是否是異步同步。即使它是異步的,並且在db關閉後你不需要做任何事情,那應該沒問題,因爲異步db.close()只是發出關閉事件,事件循環會繼續處理它,無論服務器是否退出。
+0

嘿本,感謝您的回答。 你能提供一些關於這段代碼的更多解釋嗎?我所熟悉的信號是'SIGINT'和'exit',其他的是什麼?另外,爲什麼你要檢查'sig'是否是'string'?並假設'db.close'是異步它不會在那裏完成嗎? –

相關問題