我現在是Node的初學者。我知道回調會阻止節點在等待I/O或其他進程時被阻塞,但Node在等待I/O完成時正在做什麼?我在nodejitsu上閱讀的一篇教程說:「回調函數是完成給定任務時調用的函數;這可以防止任何阻塞,並允許其他代碼在此期間運行。」但是其他代碼正在運行?假設給定塊的其他代碼依賴於從數據庫中檢索的信息。節點可以在等待回調的同時處理其他連接,還是隻能在當前塊中運行其他代碼?等待回調節點時運行任意代碼?
回答
它在等待時什麼都不做。但它可能會等待多個IO操作完成,然後將調用首先完成的回調。因此,如果您正在等待多個連接,則每當連接打開時,節點都會執行某些操作。它甚至會這樣做,如果由第一個連接觸發的某些代碼在此期間註冊了一個回調來等待某個文件IO。
節點工作過的事件隊列。當您開始異步操作時,該操作將獨立於後臺節點進行。節點繼續在當前執行線程中運行代碼的其餘部分,直到它到達該執行線程的末尾(例如,所有內容都返回到堆棧的頂部)。當節點運行當前執行線程時,沒有其他執行線程會在節點中運行(忽略當前的發生器和光纖)。這就是爲什麼人們稱它爲單線程。它按順序依次運行一個特定的執行線程,而不是並行執行多個線程。必須在下一次運行之前完成。
當執行完畢的一個線程,如果有事件隊列中的其他事件,則節點將會彈出隊列中的下一個事件並運行它。事件隊列中的其他事件可以來自任何事物。它們可以來自計時器,來自剛剛開始的異步事件或來自程序中其他地方的異步事件(例如在您的特定問題中完成的其他數據庫操作)。如果沒有其他事件(因此沒有準備好運行的代碼),那麼節點只是等待,直到發生下一個事件(除垃圾收集之外什麼都不做)。
然後,當異步操作(背景)完成,它將事件添加到事件隊列調用它的回調。如果當時沒有其他節點正在運行,那麼異步回調事件將會運行。如果別的東西在節點正在運行,則該操作將完成執行,並且當它在事件隊列中的下一個事件將運行等等...
這樣,只有永遠的一個線程在nodejs中一次執行。當一個完成時,nodejs執行引擎從事件隊列中獲取下一個事件並運行它。當異步操作完成並想要調用其回調時,它們將事件插入到事件隊列中。
This answer描述事件隊列幷包含一些其他引用是爲瀏覽器編寫的,但幾乎所有相同的規則都適用於nodejs,因此它可能也有助於您更好地理解這一點。
- 1. 節點不是等待回調
- 2. 節點腳本等待異步回調
- 3. 等待回調在節點中完成
- 4. 在編譯時運行任意代碼
- 5. Java運行進程:在任意進程運行時查看字節代碼
- 6. Cassandra:協調節點超時等待複製節點的響應
- 7. 在節點中,你如何等待回調被調用?
- 8. 正在等待的任務:返回任務,或等待如果沒有代碼後等待
- 9. iPhone等待代碼執行
- 10. 等待任務運行? /任務完成時跳轉下一行?
- 11. 如何在等待ajax回調時運行javascript
- 12. 讓我的代碼等待時間線正在運行
- 13. 做異步/等待時意外的標識符(節點:8.1.4)
- 14. 節點回調承諾與異步/等待
- 15. 回調得到解決而不等待節點js
- 16. node.js等待回調
- 17. Grunt watch運行「看」任務等待
- 18. iPhone - 正在等待異步任務的代碼行要執行
- 19. 同步運行節點sqlite3代碼
- 20. npm掛起,等待節點
- 21. await任務裏面等待的任務 - 其他代碼何時執行?
- 22. 節點同步運行,等待循環完成
- 23. 在Apache Spark中的多個節點上運行代碼時的注意事項
- 24. matplotlib:故意阻止代碼執行等待GUI事件
- 25. 節點js等待request.get回調發生,然後轉到下一行
- 26. MATLAB任意代碼執行
- 27. 如何在django shell啓動時運行任意代碼?
- 28. 在重新加載Rails插件時運行任意代碼
- 29. 執行了等待一個std :: condition_variable在「等待回調」通知
- 30. 異步等待MVC行動返回任務的代替的ActionResult
這是節點的一個重要概念,每個人都必須繞到他們頭上沒有其他排隊的事件將運行至當前運行的函數返回所有的方式回到了它的調用堆棧,達到腳本和結束時退場。只有這樣下一個事件纔會出列並運行。 (光纖和發生器不包括在內) – Andras 2014-12-03 19:16:00
@ jfriend00你講單線程的方式使它看起來像一個普通的同步程序。如果Node正在等待數據庫I/O,它是否會將其他就緒任務從事件隊列中彈出或者是否卡在當前正在執行的塊中?假設我有一條到/的路徑,並且它首先訪問文件系統。在等待文件系統完成檢索文件的同時,節點是否可以脫離該塊並處理其他連接? – user137717 2014-12-03 20:39:47
@ user137717 - 在執行任何其他代碼之前,單個執行線程一直運行直到完成。如果您的節點服務器正在提供請求,然後使用設置的回調進行數據庫調用,然後返回到系統,則節點完全可以自由地執行其他任何操作(包括服務其他傳入請求)。在將來的某個時候,當數據庫調用完成時,節點將調用回調,並且您的請求將完成它的工作。 – jfriend00 2014-12-03 21:04:45