本系列包括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();
複製代碼
獲得它了?讓咱們快速看一下在瀏覽器中運行此代碼時發生的狀況: