首頁  >  文章  >  web前端  >  js中的event-loop的詳細介紹(圖文)

js中的event-loop的詳細介紹(圖文)

不言
不言原創
2018-08-27 09:51:551534瀏覽

本篇文章帶給大家的內容是關於js中的event-loop的詳細介紹(圖文) ,有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

瀏覽器渲染

從耗時的角度,瀏覽器請求、載入、渲染一個頁面,時間花在下面五件事:
1.DNS 查詢
2.TCP 連線
3.HTTP 請求即回應
4.伺服器回應
5.客戶端渲染

這裡重點討論第五部分,即瀏覽器對內容的渲染,這一部分(渲染樹構建,佈局和繪製),又可以分為下面的五個部分。

1.處理 HTML 標記並建立 DOM 樹。
2.處理 CSS 標記並建立 CSSOM 樹。
3.將 DOM 與 CSSOM 合併成一個渲染樹。
4.根據渲染樹來佈局,以計算每個節點的幾何資訊。
5.將各個節點繪製到螢幕上。

這些並不是本文正文,只是說在完成以上過程之後,整個頁面就已經出來了,這個時候瀏覽器是否就已經處於空閒狀態了呢(不考慮動畫、交互等處理)?接下來就是本文的重點了。

堆疊、堆疊、佇列

了解重點之前我們先了解一點簡單的基礎知識,堆疊、堆疊、佇列;

堆疊

物件被分配在一個堆中,即用以表示一個大部分非結構化的記憶體區域。

這是程式執行時需要為對new操作產生的物件分配儲存空間,是沒有特別限制的儲存空間。

堆疊

函數呼叫形成一個堆疊訊框;

堆疊的特點:先進後出(First in, last out)函數執行堆疊過程;可以看成是每次函數first運行時,將函數入棧,此時函數中的其他運行函數(second函數)需要再次入棧,執行完該second函數之後,該second函數將會出棧,繼而完成first的執行,執行完成後,first將會出棧;

js中的event-loop的詳細介紹(圖文)

佇列

佇列是一種和堆疊不一樣的資料結構,類似管道,先進入的將會現出來,和堆疊是相反的。

event-loop

javascript從誕生之日起就是一門單執行緒的非阻塞的腳本語言。這是由其最初的用途決定的:與瀏覽器互動。
單執行緒意味著,javascript程式碼在執行的任何時候,都只有一個主執行緒來處理所有的任務。
而非阻塞則是當程式碼需要進行一項非同步任務(無法立刻回傳結果,需要花一定時間才能回傳的任務,如I/O事件)的時候,主執行緒會掛起(pending)這個任務,然後在非同步任務返回結果的時候再根據一定規則去執行對應的回呼。
單線程是必要的,也是javascript這門語言的基石,原因之一在其最初也是最主要的執行環境——瀏覽器中,我們需要進行各種各樣的dom操作。試想 如果javascript是多執行緒的,那麼當兩個執行緒同時對dom進行一項操作,例如一個向其添加事件,而另一個刪除了這個dom,此時該如何處理呢?因此,為了確保不會 發生類似這個例子中的情景,javascript選擇只用一個主執行緒來執行程式碼,這樣就保證了程式執行的一致性。
當然,現如今人們也意識到,單執行緒在保證了執行順序的同時也限制了javascript的效率,因此開發出了web worker技術。這項技術號稱讓javascript成為一門多執行緒語言。
然而,使用web worker技術開的多執行緒有著許多限制,例如:所有新執行緒都受主執行緒的完全控制,不能獨立執行。這意味著這些「線程」 實際上應屬於主執行緒的子執行緒。另外,這些子執行緒並沒有執行I/O操作的權限,只能為主執行緒分擔一些諸如運算等任務。所以嚴格來講這些線程並沒有完整的功能,也因此這項技術並非改變了javascript語言的單線程本質。
可以預見,未來的javascript也會一直是單線程的語言。

那麼為了能夠很好地提高的腳本的效率,故而設計的時候有一個非常有趣的特性是事件循環模型,與許多其他語言不同,它永不阻塞。處理 I/O 通常透過事件和回呼來執行,所以當一個應用程式正等待IndexedDB查詢返回或一個 XHR 請求返回時,它仍然可以處理其它事情,例如使用者輸入。

macro task與micro task

  1. 先執行script,script稱為全域任務,也屬於macrotask;

  2. 當macrotask執行完以下,執行所有的微任務;

  3. 微任務全部執行完,再取任務佇列中的一個巨集任務執行。

巨集任務包含:script, setTimeout, setInterval, setImmediate, I/O,UI rendering,requestAnimationFrame
微任務包括:process.nextTick(node api), 原生Promise(有些實現的promise將then方法放到了宏任務中),Object.observe(已廢棄), MutationObserver

執行順序

所有的宏任務放在一個宏任務隊列(即任務隊列),處理完一個宏任務(從sccript開始),將微任務隊列(包含當時所有的微任務)壓入任務隊列(宏任務隊列)並執行,之後再取下一個任務隊列(宏任務)中的宏任務。

js中的event-loop的詳細介紹(圖文)

相關推薦:

#javascript如何實作刪除表格中勾選的行(程式碼)

javascript中動態加入td標籤和tr標籤的方法(程式碼)

#

以上是js中的event-loop的詳細介紹(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn