簡體   English   中英

Node.js 中的事件循環

[英]Event loop in Node.js

我們都知道,在 Node.js 中,函數由工作線程處理執行,然后發送到事件隊列,然后事件循環查看調用堆棧。 如果調用堆棧為空,則事件循環將函數的上下文環境用於調用堆棧,然后調用堆棧對其進行處理並將其作為響應。

我的問題是,如果我們有多個具有相同超時函數的函數,然后將所有函數都交給工作線程,然后工作線程將它們的上下文環境發送到事件隊列,如果所有函數的超時都相同,那么它們都進入事件隊列同時,如果調用棧為空,則事件循環會將所有的函數都發送到調用棧中,我們都知道棧的屬性是FILO。

因此,如果發生這種情況,則應首先發送最后一個函數作為響應,但如果所有超時都相同,則第一個函數將首先響應?

您在問題中描述事物的方式有很多錯誤,但我會談談您提出的超時問題。

nodejs 有自己的計時器系統。 它保留了一個排序的計時器列表,並且唯一具有物理系統計時器的 Javascript 超時是下一個要觸發的。 如果多個 Javascript 超時設置為在同一時間點觸發,則它們都共享一個操作系統計時器。

當該操作系統計時器觸發並且主 JS 線程空閑並且能夠從事件循環中提取下一個事件時,它將看到一個 JS 計時器已准備好調用其回調。 如果有多個准備就緒,並且所有時間都在同一時間,那么解釋器將按照定時器的配置順序(FIFO)一個接一個地調用它們的每個回調。

我們都知道,在 Node.js 中,函數由工作線程處理執行,然后發送到事件隊列,然后事件循環查看調用堆棧。 如果調用堆棧為空,則事件循環將函數的上下文環境用於調用堆棧,然后調用堆棧對其進行處理並將其作為響應。

我的問題是,如果我們有多個具有相同超時函數的函數,然后將所有函數都提供給工作線程

那部分是錯誤的。 它們不會提供給工作線程。

然后工作線程將它們的上下文環境發送到事件隊列,如果所有函數的超時時間都相同,則它們都同時進入事件隊列

如上所述,計時器是事件循環代碼中的一種特殊類型的事件。 他們一次只使用一個系統計時器來安排下一個計時器觸發。 設置為同時觸發的多個計時器都存儲在同一個列表(該特定時間的列表元素)中,並且在輪到下一個時共享同一個操作系統計時器。 因此,它們不會同時進入事件隊列。 Nodejs 為設置為同時觸發的一組計時器設置了一個系統計時器。 當該系統計時器觸發並且解釋器可以自由地從事件循環中提取下一個事件時,它將以 FIFO 順序為該時間設置的每個計時器依次調用每個回調。

然后如果調用棧為空則事件循環會將所有函數發送到調用棧,我們都知道棧的屬性是FILO。

我不知道“將所有函數發送到該調用堆棧”是什么意思。 事情根本不是這樣的。 node.js 在單個線程中運行您的 Javascript(除了 WorkerThreads 不在此處運行),因此它會調用一個計時器的回調,將其運行到完成,然后調用下一個計時器的回調,將其運行到完成等等在...

因此,如果發生這種情況,則應首先發送最后一個函數作為響應,但如果所有超時都相同,則第一個函數將首先響應?

正如我在上面多次說過的,多個定時器設置為同時觸發,使用一個系統定時器,當該系統定時器觸發時,每個定時器的回調按 FIFO 順序依次調用。


參考

您可以在此處了解有關 node.js 計時器架構的更多信息: Node.js 如何管理計時器

而且,這里有一些關於 node.js 計時器架構的更多信息來自源代碼中的評論:在性能問題之前有多少並發 setTimeouts? .

在設置大量計時器或使用計划任務隊列之間尋找解決方案

Node.js 事件循環及其工作原理的六部分系列

我的問題是我們是否有多個具有相同超時功能的功能

輪詢階段控制定時器

首先閱讀這里

我強烈推薦這個系列

所以主要的問題是 Node 如何決定接下來運行什么代碼?

正如我們所知,事件循環和工作池分別維護待處理事件和待處理任務的隊列。

不要與 Worker 線程混淆


工作線程是不同的概念閱讀這里

但實際上,事件循環實際上並不維護隊列。 相反,它有一組文件描述符,它要求操作系統使用 epoll (Linux)、kqueue (OSX)、事件端口 (Solaris) 或 IOCP (Windows) 等機制進行監視。 這些文件描述符對應於網絡套接字、它正在監視的任何文件等。 當操作系統說這些文件描述符之一已准備好時,事件循環將其轉換為適當的事件並調用與該事件關聯的回調

Worker Pool 使用一個真正的隊列,其條目是要處理的任務。 一個 Worker 從這個隊列中彈出一個任務並對其進行處理,當完成時,該 Worker 為事件循環引發“至少一個任務已完成”事件。

定時器回調的調用取決於系統的性能(節點必須在執行回調之前檢查定時器是否過期,這需要一些 CPU 時間)以及事件循環中當前正在運行的進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM