做者:Lydia Halliejavascript
譯者:前端小智前端
來源: devjava
點贊再看,養成習慣git
本文
GitHub
github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。github
事件循環是什麼,爲何要理解它?面試
JS 是單線程的:一次只能運行一個任務。一般這沒什麼大不了的,但如今想象一下咱們正在運行一個須要30秒
的任務。在這個任務中,咱們要等待30秒
,而後才能執行接下來要作的事情(JS 默認運行在瀏覽器的主線程上,因此整個UI都卡住了)。瀏覽器
幸運的是,瀏覽器提供了 JS 引擎自己沒有提供的一些特性:Web API。這包括DOM API、setTimeout
、HTTP
請求等等。這些 API 能夠幫助咱們建立一些異步的、非阻塞的行爲。異步
當咱們調用一個函數時,它被添加到調用堆棧中。調用堆棧是JS引擎的一部分,這不是瀏覽器特有的。堆棧裏面的順序是先進後出,當函數返回一個值時,它會從堆棧中彈出。函數
response
函數返回一個setTimeout
函數。setTimeout
是由Web API提供的:它容許咱們在不阻塞主線程的狀況下延遲任務。咱們傳遞給setTimeout
函數的回調函數()=> {return 'Hey'}
被添加到Web API中。與此同時,setTimeout
函數和response
函數從堆棧中彈出,它們都返回了它們的值。工具
在Web API中,計時器的運行時間與咱們傳遞給它的第二個參數1000ms
同樣長。 回調不會當即添加到調用堆棧中,而是會傳遞到隊列中。
這多是一個使人困惑的部分:它並不意味着在1000ms
以後將回調函數添加到調用堆棧中,它只是在1000ms
後添加到隊列中。在隊列,函數必須等待輪到它,纔會執行。
如今,咱們一直在等待事件循環完成其唯一的任務:將隊列與調用堆棧鏈接起來。若是調用堆棧爲空,那麼若是以前調用的全部函數都返回了它們的值並已從堆棧中彈出,則隊列中的第一項將添加到調用堆棧中。在本例中,沒有調用其餘函數,這意味着在回調函數成爲隊列中的第一項時,調用堆棧爲空。
回調函數被添加到調用堆棧中,被調用,並返回一個值,而後從堆棧中彈出。
經過動畫演示看起來是頗有趣的,但仍是須要重複多看幾遍,才能更好理解它們之間的關係。如今來考驗一下,以下代碼所示,請說出執行的結果:
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
,setTimeou
t函數和bar
從調用棧中彈出。
3.計時器運行,同時函數foo
被調用並打印 First
。 foo
返回,接着調用函數baz
,並將回調添加到隊列中。
4.函數baz
打印Third
,事件循環看到baz
返回後,調用棧爲空,而後將處理隊列中的回調添加到調用棧中。
Second
。但願本文對你在事件循環上的理解有必定的幫助,我們下篇見。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
交流
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。