【第1790期】圖解Event Loop

2021-02-20 前端早讀課

前言

通過生動形象的動圖講解事件循環的一些基本概念。今日早讀文章由@Logan70翻譯授權分享。

正文從這開始~~

事件循環(Event Loop),是每個JS開發者都會接觸到的概念,但是剛接觸時可能會存在各種疑惑。我是一個視覺型學習者,所以打算通過gif動圖的可視化形式幫助大家理解它。

首先我們來看看,什麼是事件循環,我們為什麼要了解它呢?

眾所周知,JavaScript是 單線程(single-threaded) 的,也就是同一時間只能運行一個任務。一般情況下這並沒有什麼問題,但是假如我們要運行一個耗時30秒的任務,我們就得等待30秒後才能執行下一個任務(這30秒期間,JavaScript佔用了主線程,我們什麼都不能做,包括頁面也是卡死狀態)。這都9012年了,不帶這麼坑爹的吧?

好在瀏覽器向我們提供了JS引擎不具備的特性:Web API。Web API包括DOM API、定時器、HTTP請求等特性,可以幫助我們實現異步、非阻塞的行為。

當我們調用一個函數時,函數會被放入一個叫做調用棧(call stack,也叫執行上下文棧)的地方。調用棧是JS引擎的一部分,並非瀏覽器特有的。調用棧是一個棧數據結構,具有後進先出的特點(Last in, first out. LIFO)。當函數執行完畢返回時,會被彈出調用棧。

圖例中的respond函數返回一個setTimeout函數調用,setTimeout函數是Web API提供給我們的功能:它允許我們延遲執行一個任務而不用阻塞主線程。setTimeout被調用時,我們傳入的回調函數,即箭頭函數 ()=>{return'hey'}會被傳遞給Web API處理,然後setTimeout和respond依次執行完畢出棧。

在Web API中會執行定時器,定時間隔就是我們傳入setTimeout的第二個參數,也就是1000ms。計時結束後回調函數並不會立即進入調用棧執行,而是會被加入一個叫做 任務隊列(Task Queue) 的地方。

看到這裡,有些人可能會疑惑:1000ms之後,回調竟然沒有放入調用棧執行,而是被放入了任務隊列,那什麼時候被執行呢?不要急,既然是一個隊列,那就要排排坐,吃果果。

接下來就是我們期待已久,萬眾矚目的 事件循環(Event Loop) 閃亮登場的時刻了。Event Loop的工作就是連接任務隊列和調用棧,當調用棧中的任務均執行完畢出棧,調用棧為空時,Event Loop會檢查任務隊列中是否存在等待執行的任務,如果存在,則取出隊列中第一個任務,放入調用棧。

我們的回調函數被放入調用棧中,執行完畢,返回其返回值,然後被彈出調用棧。

閱讀一時爽,但只有通過反覆練習,將其變為自己的東西後才會一直爽。我們來做個小練習檢測下學習成果,看看下面代碼輸出什麼:

const foo = () => console.log('First');

const bar = () => setTimeout(() => console.log('Second'), 500);

const baz = () => console.log('Third');

bar();

foo();

baz();

相信大家都可以輕鬆給出正確答案。我們一起來看下這段代碼運行時發生了什麼:

bar被調用,返回setTimeout的調用;

傳入setTimeout的回調被傳遞給Web API處理,setTimeout執行完畢出棧,bar執行完畢出棧;

定時器開始運行,同時主線程中foo被調用,列印First,foo執行完畢出棧;

baz被調用,列印Third,baz執行完畢出棧;

500ms後定時器運行完畢,回調函數被放入任務隊列;

Event Loop檢測到調用棧為空,從任務隊列中取出回調函數放入調用棧;

回調函數被執行,列印Second,執行完畢出棧。

關於本文譯者:@Logan70譯文:https://github.com/logan70/Blog/issues/25作者:@Lydia Hallie原文:https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif

為你推薦

【第1405期】瀏覽器的 Event Loop

【第993期】總是一知半解的Event Loop

【第1431期】圖解瀏覽器的基本工作原理

相關焦點

  • 深入理解 Event Loop
    本文就瀏覽器與nodejs環境下異步實現與event loop進行相關解釋。瀏覽器環境瀏覽器環境下,會維護一個任務隊列,當異步任務到達的時候加入隊列,等待事件循環到合適的時機執行。比較具體的是這樣:event-loop startmicroTasks 隊列開始清空(執行)檢查 Tasks 是否清空,有則跳到 4,無則跳到 6從 Tasks 隊列抽取一個任務,執行檢查 microTasks 是否清空,若有則跳到 2,無則跳到 3結束 event-loop也就是說,microTasks
  • Event Loop淺談
    event loop 即事件循環。最初了解到js的event loop機制是通過自己對js中異步、同步的疑惑。
  • 【小心得】淺析Nodejs Event Loop
    每一個階段都有一個裝有callbacks的fifo queue(隊列),當event loop運行到一個指定階段時,node將執行該階段的fifo queue(隊列),當隊列callback執行完或者執行callbacks數量超過該階段的上限時,event loop會轉入下一下階段.
  • 你不知道的 Event Loop
    In computer science, the event loop is a programming construct or design pattern that waits for and dispatches events or messages in a program.
  • 一次弄懂Event Loop
    Node的Event loop一共分為6個階段,每個細節具體如下:timers: 執行setTimeout和setInterval中到期的callback。startendpromise3timer1timer2promise1promise2具體詳情可以查看《又被node的eventloop坑了,這次是node的鍋》(https://juejin.im/post/5c3e8d90f265da614274218a)。
  • 一篇文章教會你 Event loop——瀏覽器和 Node
    但是發現整個Event loop儘管有很多篇文章,但是沒有一篇可以看完就對它所有內容都了解的文章。大部分的文章都只闡述了瀏覽器或者Node二者之一,沒有對比的去看的話,認識總是淺一點。所以才有了這篇整理了百家之長的文章。1. 定義Event loop:即事件循環,是JavaScript引擎處理異步任務的方式。
  • 如何解釋Event Loop面試官才滿意?
    異步任務則不進入主線程,而是先在event table中註冊函數,當滿足觸發條件後,才可以進入任務隊列來執行。只有任務隊列通知主線程說,我這邊異步任務可以執行了,這個時候此任務才會進入主線程執行。2.setTimeout是異步任務,先被放入event table中註冊,1000ms之後進入任務隊列。3.console.log(c)是同步任務,進入主線程執行,列印c。當a,c被列印後,主線程去事件隊列中找到setTimeout裡的函數,並執行,列印b。
  • 【第1589期】圖解 Map、Reduce 和 Filter 數組方法
    juejin.im/post/5caf030d6fb9a068736d2d7c作者:Una Kravets作者:https://css-tricks.com/an-illustrated-and-musical-guide-to-map-reduce-and-filter-array-methods/校對者:@Endone、@Reaper622為你推薦【第1431
  • Event Loop的規範和實現
    我再次確認了HTML規範,發現雖然有4ms的限制,但是是存在條件的,詳見規範第11點:If nesting level is greater than 5, and timeout is less than 4, then set timeout to 4.並且有意思的是,MDN英文文檔的說明也已經貼合了這個規範。
  • 深入解析 EventLoop 和瀏覽器渲染、幀動畫、空閒回調的關係
    進入更新渲染階段,判斷是否需要渲染,這裡有一個 rendering opportunity 的概念,也就是說不一定每一輪 event loop 都會對應一次瀏覽 器渲染,要根據屏幕刷新率、頁面性能、頁面是否在後臺運行來共同決定,通常來說這個渲染間隔是固定的。
  • #美國2020年人口普查# 1790年人口普查
    census act, March 1, 1790.Census)1790年3月1日,喬治·華盛頓總統,副總統約翰·亞當斯和眾議院議長弗雷德裡克·米倫伯格籤署1790年人口普查法。(照片:美國人口調查局)#美國2020年人口普查# 1776年美國獨立,獨立後的第14年聯邦政府實施了全國性的人口普查,1790年成為首次人口普查之年。其後全國性的人口普查每10年一次,今年的人口普查為第24次。
  • 六期 秋兒芭比娃衣原創圖解
    用針:1.75mm用線:五號蕾絲    萌娃娃試鉤:秋兒拍照:秋兒六期娃衣上衣     R134CH     圈鉤R2-R334XR48X    4CHR6-R830XR96(4X  V)R10-R1136X    鉤邊19X留線編辮子耳朵*2R17XR2A   3X   AR3A  X  AR4X   AR5A  2CH鼻子   R1‍5X圈鉤R25V1:加入娃衣微信群(押金十元)2:關注公眾號(自願,並不強制,公開圖解會通過本公眾號發出
  • EventLoop面試必考,你完全會了麼?
    ();1、李兵老師的瀏覽器工作原理與實踐(這是一個付費專欄,以下連結不屬於這個專欄) 2、https://juejin.im/post/6844903512845860872 3、https://www.jianshu.com/p/2771cb695c81 4、https://html.spec.whatwg.org/multipage/webappapis.html#event-loops
  • 前端書薦-計算機網絡篇-第1期《圖解HTTP》
    各位好,我是前端厚說小洋同學 本期給大家帶來前端書薦計算機網絡系列的第一期——《圖解HTTP》書籍概況主要從 豆瓣評分 適合讀者 書籍風格 三大橫向維度來拆解豆瓣評分image-20210703221400359
  • 事件循環Event Loop
    Promise(function(resolve){  console.log('2');  resolve();}).then(function(){console.log('3')});console.log('4');//2  4  3  1(1)settimeout是宏任務,雖然先執行的他,但是他被放到了宏任務的eventqueue
  • 面試官:什麼是 EventLoop.你:一臉蒙蔽.看完這篇文章就懂了
    看完這篇文章就懂了文章翻譯自:https://javascript.info/event-loop在這片文章,我們要帶著兩個問題去學習事件循環瀏覽器 js 以及現在,如果 onclick 在引擎正在忙於執行第1部分時出現新的輔助任務(例如事件),則將其排隊,然後在第1部分完成時在下一部分之前執行。count 執行之間定期返回事件循環為 JavaScript 引擎提供了足夠的「空氣」來執行其他操作,以對其他用戶操作做出反應。
  • JS基礎:Event loop事件循環解析
    在node v12版本後,瀏覽器端與node端Event loop實現保持一致,在這篇文章我們將綜合討論
  • Windows 10 LTSC 2019 Build 17763.1790
    [LTSC & Server 2019 & CMGE]17763.1790 原版集成 ISO 21年2月第2次更新by ananhaid* 母版選用官方初始版,沒有添加任何第三方數據,完全原版* 採用官方渠道原版集成相關最新補丁整合而成,提供三個版:☑ Windows 10 企業版 2019 長期服務版,單一ISO鏡像,提供32位和
  • jsliang 求職系列 - 06 - Event Loop
    事件循環機制(Node.js篇)【閱讀建議:無】詳解 JavaScript 中的 Event Loop(事件循環)機制【閱讀建議:5min】深入理解 JavaScript Event Loop【閱讀建議:20min】【THE LAST TIME】徹底吃透 JavaScript 執行機制【閱讀建議:20min】JavaScript:徹底理解同步、異步和事件循環(Event Loop)【閱讀建議:10min】從event
  • EventLoop 系列 - 聊聊 Node.js 中的事件循環
    下圖展示了它的組成部分,Network I/O 是網絡處理相關的部分,右側還有文件操作、DNS,底部 epoll、kqueue、event ports、IOCP 這些是底層不同作業系統的實現。https://cnodejs.org/topic/5a9108d78d6e16e56bb80882https://cnodejs.org/topic/57d68794cb6f605d360105bfReferencehttp://docs.libuv.org/en/v1.x/design.htmlhttps://nodejs.org/zh-cn/docs/guides/event-loop-timers-and-nexttickJavaScript