事件循環(huán)是用來理解JavaScript的最重要的方面之一。這篇文章旨在解釋JavaScript如何與單個線程一起工作的細節(jié),以及它如何處理異步函數(shù)。
JavaScript代碼運行是單線程。一次只執(zhí)行一件事。這實際上是一個非常有用的限制,因為它簡化了很多程序,從而不必擔心并發(fā)問題。
您只需要注意編寫代碼的方式,避免任何可能阻塞線程的內(nèi)容,如同步調(diào)用或無限循環(huán)。
通常,在大多數(shù)瀏覽器中,每個瀏覽器都有一個事件循環(huán),以使每個進程隔離,并避免web頁面具有無限循環(huán)或繁重的處理來阻塞整個瀏覽器。
你最需要擔心的是,您的代碼將在單個事件循環(huán)上運行,并在編寫代碼時考慮到這一點,以避免阻塞它。
阻止事件循環(huán)
任何花費太長時間將控制權(quán)返回給事件循環(huán)的JavaScript代碼都會阻止頁面中任何JavaScript代碼的執(zhí)行,甚至阻止UI線程,用戶也無法點擊,滾動頁面等等。
幾乎所有JavaScript中的I / O操作都是非阻塞的。網(wǎng)絡(luò)請求,Node.js文件系統(tǒng)操作等。阻塞是個例外,這就是為什么JavaScript基于回調(diào),以及最近的promises和async / await。
調(diào)用堆棧
調(diào)用堆棧是LIFO隊列(Last In,F(xiàn)irstOut)。事件循環(huán)不斷檢查調(diào)用堆棧以查看是否存在需要運行的任何函數(shù)。
在執(zhí)行此操作時,它會將它找到的任何函數(shù)調(diào)用添加到調(diào)用堆棧并按順序執(zhí)行每個調(diào)用。
一個簡單的事件循環(huán)說明:
當此代碼運行時,首先foo()調(diào)用。在foo()我們第一次調(diào)用bar(),然后我們調(diào)用baz()。
排隊功能執(zhí)行
上面的例子運行特點:JavaScript找到要執(zhí)行的東西,按順序運行它們。
讓我們看看如何推遲函數(shù)直到堆棧清除:
用例setTimeout(()=> {}), 0)是調(diào)用一個函數(shù),但是一旦執(zhí)行了代碼中的每個其他函數(shù)就執(zhí)行它。
當此代碼運行時,首先調(diào)用foo()。在foo()里面我們首先調(diào)用setTimeout,bar作為參數(shù)傳遞,然后我們指示它盡可能快地運行,將0作為計時器傳遞。然后我們調(diào)用baz()。
消息隊列
調(diào)用setTimeout()時,瀏覽器或Node.js啟動計時器。當計時器到期,我們將0作為超時,回調(diào)函數(shù)立即被放入消息隊列中。
消息隊列也是用戶發(fā)起的事件(如單擊事件、鍵盤事件或獲取響應(yīng))在代碼有機會對其作出響應(yīng)之前排隊的地方。或者像onLoad這樣的DOM事件。
循環(huán)優(yōu)先處理調(diào)用堆棧,它首先處理在調(diào)用堆棧中找到的所有東西,一旦調(diào)用堆棧中沒有任何東西,它就會去獲取事件隊列中的東西。
我們不必等待像setTimeout,fetch或其他東西這樣的函數(shù)來完成自己的工作,因為它們是由瀏覽器提供的,并且它們運行在自己的線程中。
ES6作業(yè)隊列
ECMAScript 2015引入了Promises使用的作業(yè)隊列概念(也在ES6 / ES2015中引入)。這是一種盡快執(zhí)行異步函數(shù)結(jié)果的方法,而不是放在調(diào)用堆棧的末尾。
在當前函數(shù)結(jié)束之前解析的Prom將在當前函數(shù)之后立即執(zhí)行。
我覺得在游樂園里過山車的比喻很好:消息隊列將你放在隊列的后面,在所有其他人的后面,你將不得不等待輪到你,而作業(yè)隊列是快速通票這可以讓你在完成上一個之后再騎一次。
這是Promises(和Async / await,它建立在promises上)和普通的舊異步函數(shù)setTimeout()或其他平臺API 之間的巨大差異。
javascrit的事件循環(huán)是這門語言中非常重要且基礎(chǔ)的概念。清楚的了解了事件循環(huán)的執(zhí)行順序和每一個階段的特點,可以使我們對一段異步代碼的執(zhí)行順序有一個清晰的認識,從而減少代碼運行的不確定性。合理的使用各種延遲事件的方法,有助于代碼更好的按照其優(yōu)先級去執(zhí)行。
-
Web
+關(guān)注
關(guān)注
2文章
1263瀏覽量
69508 -
javascript
+關(guān)注
關(guān)注
0文章
519瀏覽量
53875
發(fā)布評論請先 登錄
相關(guān)推薦
評論