2015-11-04 76 views
1

我已經看到類似的堆棧溢出問題,但沒有一個完全潛入我的問題?我熟悉事件隊列,他們如何工作以及如何實施。我是node.js的新手,我試圖圍繞Node.js如何實現它。node.js事件隊列在哪裏?

在C++應用程序,你會做線沿線的東西:

int main(){ 
    std::vector<Handler*> handlers; 
    BlockingQueue queue = new BlockingQueue(); 
    //Add all the handlers call constructors and other such initialization 

    //Then run the event loop 
    while(true){ 
     Event e = queue.pop(); 

     for(std::vector<Handler>::iterator it = handlers.begin(); it != handlers.end(); ++it){ 
      *it.handle(e); 
     } 
    } 
} 

現在的Node.js的情況下,我可能有一個名爲main.js一主文件看起來像。

var http = require("http"); 
function main(){ 
    // Console will print the message 
    console.log('Server running at http://127.0.0.1:8080/'); 
    var server = http.createServer(function (request, response) { 

     // Send the HTTP header 
     // HTTP Status: 200 : OK 
     // Content Type: text/plain 
     response.writeHead(200, {'Content-Type': 'text/plain'}); 

     // Send the response body as "Hello World" 
     response.end('Hello World\n'); 
    }); 

    server.listen(8080); 
    console.log('Main completed'); 
} 

main(); 

我明白server.listen將一個處理程序附加到事件隊列中,並且我們正在添加類似於C++示例的回調函數。

我的問題是。事件隊列在哪裏?它是在JavaScript的某處,還是內置於解釋器?還有,主函數是如何相對於主事件循環調用的?

+0

事件隊列是內置的。當事件發生時,它將事件推入調用堆棧,也是內置的。調用堆棧中的調用在當前調用完成之前不會被調用。 – Blindman67

回答

3

事件隊列在哪裏?它是在JavaScript的某處,還是在內置於解釋器中的 ?

事件隊列內置於承載Javascript解釋器的操作環境中。它本身不是JavaScript本身的基礎,所以它不是真正的JS運行時的一部分。一個有趣的指標是setTimeout()實際上並不是ECMAScript的一部分,而是主機提供給Javascript環境的東西。

圍繞node.js中Javascript實現的系統會跟蹤外部觸發的事件(定時器,網絡結果等),並且當Javascript不忙時執行某些事情併發生外部事件時,它會觸發關聯Javascript回調。如果Javascript正在忙於執行某些操作,那麼它會對該事件進行排隊,以便一旦Javascript不再繁忙,就可以觸發隊列中的下一個事件。

node.js本身使用libuv作爲事件循環。您可以閱讀關於here的更多信息。它提供了一個多平臺的方式來完成爲node.js開發的異步I/O,但也被其他一些項目使用。

這裏有一個相關的答案,可能還有助於:

Run Arbitrary Code While Waiting For Callback in Node?

另外請問在主函數被調用相對於主事件 循環?

當node.js啓動時,會給它一個初始腳本文件來執行。它將該腳本文件加載到內存中,解析其中的Javascript並執行它。在您的特定示例中,這將導致函數main被解析,然後將導致將運行該函數的main()的執行。

加載,解析和執行傳遞給節點的腳本文件在啓動時是賦予node.js的任務。它根本不涉及事件隊列。在某些node.js應用程序中,它運行該初始腳本,然後退出(完成其工作)。在其他節點中。js應用程序,最初的腳本啓動定時器或服務器或類似未來將接收事件的事件。在這種情況下,node.js會運行初始腳本來完成,但由於現在已經創建並正在監聽事件(在您的情況下是服務器)的持久對象,nodejs不會關閉應用程序。它保持運行,以便它可以在發生時接收這些未來事件。


一個在這裏失蹤一塊是物像您所創建的服務器對象允許您註冊一個回調,當一些特定的事件發生,將被稱爲未來的一次或多次。這種行爲沒有內置到Javascript中。相反,實現這些對象或它們使用的TCP函數的代碼必須維護已註冊的回調列表,並且當這些事件發生時,它必須執行代碼,以便調用適當的回調並傳遞適當的數據。在http.createServer()的情況下,它是Javascript和本地代碼在nodejs http庫中的組合,它可以實現這一點。

+0

在操作環境中,你是指節點解釋器嗎?如果是這樣的話。在解釋器跳入事件處理之前,我的主函數是否被調用,或者它是否作爲事件進行調用? – nbroeking

+0

Node.js中的本地事件循環基於libuv構建https://en.wikipedia.org/wiki/Libuv –

+0

@nbroeking - 「操作環境」是實際解釋器周圍的代碼集,而不是Javascript解釋器本身 - 在這種情況下,解釋器是V8引擎,解釋器周圍的代碼是node.js在V8之外添加的。查看我最近添加到其他問題的答案中的其他內容。 – jfriend00