[譯]JavaScript️可視化:事件循環

本系列包括6篇文章javascript

哦,事件循環。這是每一個JavaScript開發人員都必須以一種或另外一種方式處理的事情之一,可是起初理解起來可能有些混亂。我是一個視覺學習者,因此我想我會嘗試經過gifs來幫助您。java

可是首先,事件循環是什麼,爲何要關心呢?git

JavaScript是單線程的:一次只能運行一個任務。一般,這沒什麼大不了的,可是如今想象您正在運行一個耗時30秒的任務。是的。在此任務中,咱們等待30秒才能進行其餘任何操做(默認狀況下,JavaScript在瀏覽器的主線程上運行,所以整個用戶界面都停滯了)😬到了2019年,沒有人想要一個速度慢,反應遲鈍的網站。github

幸運的是,瀏覽器爲咱們提供了JavaScript引擎自己不提供的一些功能:Web API。這包括DOM API,setTimeoutHTTP請求等。這能夠幫助咱們建立一些異步的,非阻塞的行爲 🚀瀏覽器

當咱們調用一個函數時,它會被添加到稱爲調用棧的東西中。調用堆棧是JS引擎的一部分,這不是特定於瀏覽器的。它是一個堆棧,這意味着它是先進先出的(例如一堆煎餅)。當一個函數返回一個值時,它會從堆棧中彈出👋異步

respond函數返回一個setTimeout函數。在setTimeout由Web API提供給咱們:它讓咱們拖延的任務,而不會阻塞主線程。咱們傳遞給該setTimeout函數的回調函數,箭頭函數() => { return 'Hey'}已添加到Web API。同時,setTimeout函數和respond函數從堆棧中彈出,它們都返回了它們的值!函數

在Web API中,計時器的運行時間與咱們傳遞給它的第二個參數1000ms同樣長。回調不會當即添加到調用堆棧中,而是會傳遞給稱爲隊列的東西。post

這多是一個使人困惑的部分:這並不意味着在1000毫秒後將回調函數添加到調用堆棧中(從而返回一個值)!它只是在1000毫秒後添加到隊列中。但這是一個隊列,該函數必須等待輪到它!學習

如今這是咱們一直在等待的部分……是時候讓事件循環執行其惟一的任務了:將隊列與調用堆棧鏈接起來!!若是調用堆棧爲空,即若是全部先前調用的函數都返回了它們的值並已從堆棧中彈出,則隊列中的第一項將添加到調用堆棧中。在這種狀況下,沒有其餘函數被調用,意味着當回調函數成爲隊列中的第一項時,調用堆棧爲空。網站

回調被添加到調用堆棧中,被調用,並返回一個值,並從堆棧中彈出。

知識點講完了,我們來作道題:

const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");

bar();
foo();
baz();

複製代碼

獲得它了?讓咱們快速看一下在瀏覽器中運行此代碼時發生的狀況:

  1. 咱們調用bar。bar返回一個setTimeout函數。
  2. 咱們傳遞給的回調setTimeout被添加到Web API,該setTimeout函數中,而且bar從調用堆棧中彈出。
  3. 計時器運行,同時foo調用並打印First。foo返回(未定義),baz被調用,並將回調添加到隊列中。
  4. baz打印Third。事件循環看到baz返回後調用棧爲空,而後將回調添加到調用棧。
  5. 回調日誌Second。

我的博客

github.com/abc-club/fr…

相關文章
相關標籤/搜索