2017-03-01 80 views
0

在閱讀了大量關於NodeJS事件循環之後,我仍然有一個疑問。在我們的代碼中,如果NodeJS運行時發現任何異步調用,它將它推送到在後臺線程上運行的任務/消息隊列,並且V8繼續在主線程上執行我們的進一步代碼。一旦異步任務完成,節點將檢查調用堆棧是否爲空。如果調用堆棧是空的,那麼只有節點將該回調函數在主線程上進行處理。否則,它必須等到調用堆棧爲空。NodeJS事件循環內部工作

到目前爲止,我認爲,我是正確的。

懷疑:如果異步任務結束並且調用堆棧不爲空,則回調將需要等待調用堆棧變空。現在假設,如果我的調用堆棧中有太多的調用可能需要很多次(比異步任務要少完成),並且異步任務已經提前完成,那麼不必等待調用堆棧變空。

Node是否以這種方式設計,只有回調需要等待調用堆棧變空?

回答

1

如果異步任務完成且調用堆棧不爲空,則回調將需要等待調用堆棧變空。現在假設,如果我的調用堆棧中有太多的調用可能需要很多次(比異步任務要少完成),並且異步任務已經提前完成,那麼不必等待調用堆棧變空。

沒錯。例如,如果調用fs.readFile(),然後運行長期運行的for循環,則如果讀取文件操作在for循環完成之前完成,它仍然需要等待for循環。

例如考慮這個代碼:

let fs = require('fs'); 

fs.readFile(__filename, 'utf-8', (err, data) => { 
    if (err) { 
    console.log('Error:', err.message); 
    } else { 
    console.log(data); 
    } 
}); 

for (let i = 0; i < 1e9; i++); 

readFile回調將不得不等待for循環來完成。

是否以這種方式設計了Node,只有該回調需要等待調用堆棧變空?

是的。你需要確保你沒有阻塞事件循環,通過阻止主線程用長時間運行的計算來防止調用堆棧變空。這不僅是Node,這也是所有客戶端JavaScript的工作原理。

更多詳情請參閱這樣的回答: