我的理解是(非集羣)nodejs程序中的所有代碼都運行在同一個線程中。鑑於此,我期望所有這樣的代碼將作爲同一個根事件循環的子代運行,因此,如果我們檢查了在不同回調中運行的代碼的堆棧跟蹤,我們最終還是會回溯到相同的條目(該事件循環的「調度事件」行)。但事實並非如此,我不明白爲什麼。爲什麼異常堆棧中的根條目根據上下文而有所不同?
考慮以下幾點:
function printStackTrace() {
console.log(new Error().stack);
}
printStackTrace();
setTimeout(printStackTrace, 1000);
運行率:
Error
at printStackTrace (/tmp/node/test.js:4:17)
at Object.<anonymous> (/tmp/node/test.js:7:1)
at Module._compile (module.js:446:26)
at Object..js (module.js:464:10)
at Module.load (module.js:353:32)
at Function._load (module.js:311:12)
at Array.0 (module.js:484:10)
at EventEmitter._tickCallback (node.js:190:39)
Error
at Object.printStackTrace [as _onTimeout] (/tmp/node/test.js:4:17)
at Timer.ontimeout (timers.js:94:19)
,只是在REPL運行console.log(new Error().stack);
給出了不同的根還是:
Error
at repl:1:13
at REPLServer.eval (repl.js:80:21)
at repl.js:190:20
at REPLServer.eval (repl.js:87:5)
at Interface.<anonymous> (repl.js:182:12)
at Interface.emit (events.js:67:17)
at Interface._onLine (readline.js:162:10)
at Interface._line (readline.js:426:8)
at Interface._ttyWrite (readline.js:603:14)
at ReadStream.<anonymous> (readline.js:82:12)
所以根(最底層)項目不同(分別在EventEmitter,Timer和ReadStream中) ELY)。其他回調(例如網絡)也是如此。
所以我想,無論是
- 事件循環是本機(C++)代碼,因此它不會在堆棧跟蹤顯示,和異步服務(repl.js,定時器的基本供應。 js等)使用本地v8 api調用向其註冊自己。
- 事件循環爲JavaScript,但
Error()
具有特殊的代碼隱藏這個(是不必要的實現細節)
哪個(如果任一)的這些情況下,和一般地方在的NodeJS(編輯:或v8)源可以讀取真正的根事件循環的實現嗎?
您可能希望將此問題的鏈接發送到freenode IRC上的#node.js頻道。 –