2017-10-10 127 views
5

我一直在看「解釋JavaScript事件循環」(即:瀏覽器JS運行時事件循環),這對我來說似乎不太合理,我希望有人能提供一些權威性的說明。Javascript事件循環說明

我的基本asssumption是,JS事件循環就像我們一直在UI框架了幾十年事件循環,是這樣的:

// [... some initialization ...] 

    // The Event Loop 
    while (true) { 
    if (! EventQueue.isEmpty()) { 
     event = EventQueue.pop_oldest_item(); 
     event.callback(event [or some other kind of args]); 
    } 
    // [... defer to other non-JS tasks...] 
    } 

但我一直看到的解釋(見下面的例子)是這樣的:

事件循環:

  1. 檢查(JavaScript)的調用堆棧是否爲空。

  2. 檢查回調隊列[AKA EventQueue]是否爲空。

  3. 如果調用堆棧是空的,回調隊列不爲空,則:

    一個。退出最舊的回調隊列項目。

    b。將該回調函數推入調用堆棧(並沒有提及調用該函數)。

  4. 保持循環。

這顯然隱約如下假設我上面的模型,但是有兩個關鍵的和令人不安的區別:

A.爲什麼事件循環需要檢查的是JS調用堆棧是空的?當然,每次循環時,調用堆棧都將處於相同的狀態(無論是否完全「空白」都在旁邊 - 它不需要「檢查」)。無論上次調用哪個函數都會返回,從而恢復堆棧。所以這部分沒有意義。

B.爲什麼事件循環「將回調推入JS堆棧」?事件循環不應該只是調用函數,從而創建一個合法的堆棧框架,以及從函數返回的方式,而不是提到實際執行該函數?

所以,我希望澄清,解決這些解釋,爲什麼他們實際上是正確的,或支持我強烈的懷疑,他們是不正確的。這些事件循環解釋


實例來源:

菲利普·羅伯茨:到底是什麼事件循環呢?在14:00 https://youtu.be/8aGhZQkoFbQ?t=839

打字稿高性能(冊)第83頁。

什麼是JavaScript事件循環? http://altitudelabs.com/blog/what-is-the-javascript-event-loop/

瞭解JavaScript函數處決 - 調用堆棧,事件循環,任務&更 https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1-5683dea1f5ec

回答

1

這是我回答你的問題:

的JavaScript行爲在單線程和同步的方式,所以事件回調函數將在後執行全局執行上下文彈出執行堆棧。所有事件將被添加到所謂的事件隊列中。

在全局執行上下文完成所有執行後,JS引擎將繼續檢查事件隊列內是否存在任何事件。如果JS引擎看到有一個事件,那麼它會爲回調函數創建一個新的執行上下文,並將其推送到執行堆棧上。在JS中,每次調用一個函數時,JS引擎都會創建一個執行上下文,它創建一個專用作用域,其中在該函數內部聲明的任何東西都不能從當前函數作用域之外直接訪問,並推入在執行上下文堆棧的頂部。在函數完成執行後,執行上下文將被彈出。

+0

這是我對你的回答的評論 – cambunctious

+0

我很感謝你回答,但我不知道這是如何解決我的問題。你肯定有一個事件隊列 - 這是毫無疑問的。並且描述了一個函數調用的工作方式 - 就像任何涉及堆棧框架的語言一樣(這裏稱爲執行上下文)。還有一些關於彈出堆棧的Global Execution Context - 這是沒有道理的。總之,你沒有解決我的觀點「A」和「B」。不過謝謝你的努力。 – gwideman