Javascript : Event Queue & Event Loop

閱讀時間約 7 分鐘

前言

這是第一次寫技術文章,但其實應該也只能說是蒐集很多資料並學習如何透過自己的話解釋的內容,並不能像其他大神可能分享一些很酷的技術,目標就單純是為了完成最後一週的作業(如下)。
setTimeout(function(){console.log('delay 0 sec')}, 0)
console.log('Hello!')
透過兩天左右的閱讀資料讓自己對JS在同步與非同步有更多概念,由於有許多專有名詞,因此會先針對各專有名詞作介紹,再敘述自己的看法,最後提供這次參考的網路資源

走入非同步之前

執行環境(Execution Context)
Javascript被執行的地方,在Chrome裡,就是由V8 Engine提供此環境,任何程式碼被執行與讀取的地方都是執行環境,其中又可分為下列三種類型:
  • 全域執行環境 : 預設的執行環境,也就是一開始載入JS檔案的執行環境就是全域執行環境,不在任何函式裡面的程式碼就是在全域執行環境,其功用除了創造全域變數,還會進行記憶體的指派。
  • 函式執行環境 : 就如字面上的意思,即函式被呼叫執行的環境,此執行環境可存在很多個,須注意的是其並不會產生全域物件。
  • eval函式執行環境 : eval對開發者來說是非常方便的函式,可以透過字串方式執行JS,需注意的是如透過EVAL綁定的資料未經過適當編碼與驗證,可能造成注入攻擊的產生,因此現在也較不被推薦使用,甚至在CSP(Content Security Policy,可看成Server回送給Cliet端的Http header裡面的一種安全規範)裡面已經被預設為禁止使用。
執行環境堆疊 (Execution stack)
上面提到函式執行環境可能有很多個,每一個函式被呼叫就會產生一個與之對應的執行環境,此時會透過「堆疊」這種資料結構來儲存函式執行環境,為一種「後進先出」的資料結構。
單線程 (Single-Thread)
一次只能做一件事情,如果有很多事情就會進行排隊,再逐一執行。
非同步(Asynchronous)
即為同一時間可以處理不只一件事情(註: 其他事情亦非同時進行),這在串接第三方API教材的時候就有用到,利用Ajax可以讓瀏覽器向server送出請求時,不需要等待結果仍然可以處裡其他事情,待之後收到response之後,新的內容可以隨時更新至網頁,這也是為什麼瀏覽Facebook、Gmail的時候不需要看到網頁一直重新整理。
Javascript Runtime Environment (JRE)
JRE即為Javascript執行的環境,最常使用的runtiime就是瀏覽器。我們在宣告函數時,使用到的let、const、function、if else,這些都是Javascript的一部分,但其實之前常常使用到的DOM、console.log、這些其實都不是Javascript,而是瀏覽器這個runtime開放給 Javascript 的 API。也就是說不同的runtime會提供不同的東西,例如瀏覽器的DOM就不能再Node.js執行。

研究分享

Javascript是一個同步的程式語言,代表同一時間只做一件事情,也就是一次只跑一段程式碼。但想想如果我們在讀取Facebook網頁,JS除了要渲染畫面還要透過Http請求跟後端拿資料,但如果文章資料很多的時候,在取得所有資料前就都會無法執行其他任務,造成Blocking的現象,因此JS其實也是有非同步執行的能力,讓使用者瀏覽網頁更為順暢。至於如何處理「同步」與「非同步」的動作呢,就要透過我們今天的主角 —Event Queue、 Event Loop。
上面的名詞解釋曾提到DOM其實不算Javascript語言,而是瀏覽器提供的API,讓我們使用者可以在開發時直接使用,其較常使用的API有操作DOM節點的API — document.querySelector、計時的API — setTimeout、 AJAX相關 — XMLHttpRequest。這些由runtime提供的API,不會影響主執行環境的運行,讓網頁可以同時做很多事情(非同步),而這些非同步的行為要如何進行排序呢,即透過Event Queue。Event Queue專門用來執行非同步的函式,等整個主執行環境運行結束以後,才開始依序執行事件儲列裡面的函式,屬於「先進先出」的資料結構
setTimeout(function(){console.log('delay 0 sec')}, 0) 
console.log('Hello!')
因此上述程式碼可看成,Javacript 引擎執行到瀏覽器提供的setTimeout函式時並不會真的停下來,過0秒馬上執行console.log('delay 0 sec'),是在過0秒之後將此函數放到Event Queue,這就像一個待辦清單,裡面的程式不會馬上執行,要所有的全域執行環境與函式執行環境結束後,才會開始執行Event Queue的內容。那要如何知道主環境都已經執行完程式了呢,就是透過Event loop。Event loop可以看成一個無時無刻都在執行的程式,會不斷監聽程式是否全部執行完成,如果環境堆疊是空的,就會去檢查Event Queue是不是有函式待執行,並將Queue的函式移到Stack執行這些「待辦清單」

參考資源

  1. ALPHA Camp教材
  2. [筆記] 理解 JavaScript 中的事件循環、堆疊、佇列和併發模式(Learn event loop, stack, queue, and concurrency mode of JavaScript in depth) ~ PJCHENder<br>那些沒告訴你的小細節
  3. 從「為什麼不能用這個函式」談執行環境(runtime) - Huli
  4. JavaScript 原力覺醒 - 成為絕地武士之路 :: 第 11 屆 iThome 鐵人賽
  5. Understanding Event Loop, Call Stack, Event & Job Queue in Javascript | by Rahul Sagore | Medium
  6. 所以說event loop到底是什麼玩意兒?| Philip Roberts | JSConf EU - YouTube
avatar-img
2會員
15內容數
紀錄轉職路上的點點滴滴
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Blockcyber的沙龍 的其他內容
OBJECTIVE 除了這些技術與見識的增加,與先前學習較大的差異,會強迫自己每週撰寫ORID學習筆記,並針對每週的作業,新增至少一個教材沒有提到的功能,訓練自己查資料並內化的能力。 REFLECTIVE INTERPRETIVE DECISIONAL
Objective 這週為自己設定為禮拜六完成所有課程,同時為兩個小作品「社群名單」、「電影清單」增加至少一個教材要求以外的小功能。 Reflective Interpretive S3 - A14 : 電影清單加碼功能 (codepen.io) Decisional
電影清單:前端體驗綜合實作 Objective Reflective Interpretive Decisional
Objective 因後面有幾個周末無法全空下時間學習,最近又因為專案開始進行常常會加班,為使課程可於期限內完成,為自己設定的目標就是在7/18學期2-2開始前至少完成一周的作業。現在看來至少是完成了最低的標準,並提前開始下週進度。 Reflective Interpretive
為什麼回來了? 重新開始 目前的規劃
OBJECTIVE 除了這些技術與見識的增加,與先前學習較大的差異,會強迫自己每週撰寫ORID學習筆記,並針對每週的作業,新增至少一個教材沒有提到的功能,訓練自己查資料並內化的能力。 REFLECTIVE INTERPRETIVE DECISIONAL
Objective 這週為自己設定為禮拜六完成所有課程,同時為兩個小作品「社群名單」、「電影清單」增加至少一個教材要求以外的小功能。 Reflective Interpretive S3 - A14 : 電影清單加碼功能 (codepen.io) Decisional
電影清單:前端體驗綜合實作 Objective Reflective Interpretive Decisional
Objective 因後面有幾個周末無法全空下時間學習,最近又因為專案開始進行常常會加班,為使課程可於期限內完成,為自己設定的目標就是在7/18學期2-2開始前至少完成一周的作業。現在看來至少是完成了最低的標準,並提前開始下週進度。 Reflective Interpretive
為什麼回來了? 重新開始 目前的規劃
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
套件(Package)是將程式或程式庫進行組織、分發和共享的一種方式。在軟體開發中,套件通常包含了相關的程式碼、資源文件和元數據,並提供了統一的名稱空間和版本管理。
Thumbnail
當你在開發程式時,難免會遇到各種錯誤和異常情況。這些錯誤可能是因為代碼中的錯誤、外部資源無法訪問或其他不可預期的狀況。為了提高程式的可靠性、穩定性和可維護性,我們使用「例外處理」來處理這些異常情況。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
事件(event)就是網頁中發生的某些事情,例如當用戶點擊按鈕、移動滑鼠、輸入文字等,JavaScript 能夠偵測這些事件,並執行相對應的程式碼。
Java script 中有其中兩種宣告分別是 var 跟 let var 結果: let 結果: ** let 是一種區塊的變數宣告像是 if else while for 即跳出區塊時就無法取得資料
Thumbnail
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
Thumbnail
上篇介紹的promise chain的寫法,是已經比原本好維護了沒錯,但是可讀性似乎還是有點不足,其實還可以改成用async/await的寫法,如下: E 其中,async是非同步的意思,等於是把getData()這個function定義為非同步,因此從console可以看到,test是最先被pri
Thumbnail
輸入畫面 為什麼要做驗證? 因為作為設計者,永遠不該預設使用者會乖乖照設計者的意思輸入。
Thumbnail
JavaScript在ES6新增了let, const等宣告變數的方式,其中let, const是block scope的,而var則是function scope。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
套件(Package)是將程式或程式庫進行組織、分發和共享的一種方式。在軟體開發中,套件通常包含了相關的程式碼、資源文件和元數據,並提供了統一的名稱空間和版本管理。
Thumbnail
當你在開發程式時,難免會遇到各種錯誤和異常情況。這些錯誤可能是因為代碼中的錯誤、外部資源無法訪問或其他不可預期的狀況。為了提高程式的可靠性、穩定性和可維護性,我們使用「例外處理」來處理這些異常情況。
Thumbnail
本章節旨在介紹JavaScript中的物件導向編程。內容包括類別(Class)的定義和使用,建構子的作用,以及公開,私有,受保護(Protected)等不同訪問修飾符的概念。此外,還涵蓋了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型、反射等物件導向的主要觀念。
Thumbnail
事件(event)就是網頁中發生的某些事情,例如當用戶點擊按鈕、移動滑鼠、輸入文字等,JavaScript 能夠偵測這些事件,並執行相對應的程式碼。
Java script 中有其中兩種宣告分別是 var 跟 let var 結果: let 結果: ** let 是一種區塊的變數宣告像是 if else while for 即跳出區塊時就無法取得資料
Thumbnail
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
Thumbnail
上篇介紹的promise chain的寫法,是已經比原本好維護了沒錯,但是可讀性似乎還是有點不足,其實還可以改成用async/await的寫法,如下: E 其中,async是非同步的意思,等於是把getData()這個function定義為非同步,因此從console可以看到,test是最先被pri
Thumbnail
輸入畫面 為什麼要做驗證? 因為作為設計者,永遠不該預設使用者會乖乖照設計者的意思輸入。
Thumbnail
JavaScript在ES6新增了let, const等宣告變數的方式,其中let, const是block scope的,而var則是function scope。