亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解JS瀏覽器事件循環(huán)機制

 更新時間:2019年03月27日 11:13:32   作者:我愛吃方方面  
這篇文章主要介紹了JS瀏覽器事件循環(huán)機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

先來明白些概念性內容。

進程、線程

進程是系統(tǒng)分配的獨立資源,是 CPU 資源分配的基本單位,進程是由一個或者多個線程組成的。

線程是進程的執(zhí)行流,是CPU調度和分派的基本單位,同個進程之中的多個線程之間是共享該進程的資源的。

瀏覽器內核

瀏覽器是多進程的,瀏覽器每一個 tab 標簽都代表一個獨立的進程(也不一定,因為多個空白 tab 標簽會合并成一個進程),瀏覽器內核(瀏覽器渲染進程)屬于瀏覽器多進程中的一種。

瀏覽器內核有多種線程在工作。

GUI 渲染線程:

  1. 負責渲染頁面,解析 HTML,CSS 構成 DOM 樹等,當頁面重繪或者由于某種操作引起回流都會調起該線程。
  2. 和 JS 引擎線程是互斥的,當 JS 引擎線程在工作的時候,GUI 渲染線程會被掛起,GUI 更新被放入在 JS 任務隊列中,等待 JS 引擎線程空閑的時候繼續(xù)執(zhí)行。

JS 引擎線程:

  1. 單線程工作,負責解析運行 JavaScript 腳本。
  2. 和 GUI 渲染線程互斥,JS 運行耗時過長就會導致頁面阻塞。

事件觸發(fā)線程:

當事件符合觸發(fā)條件被觸發(fā)時,該線程會把對應的事件回調函數(shù)添加到任務隊列的隊尾,等待 JS 引擎處理。

定時器觸發(fā)線程:

  1. 瀏覽器定時計數(shù)器并不是由 JS 引擎計數(shù)的,阻塞會導致計時不準確。
  2. 開啟定時器觸發(fā)線程來計時并觸發(fā)計時,計時完成后會被添加到任務隊列中,等待 JS 引擎處理。

http 請求線程:

  1. http 請求的時候會開啟一條請求線程。
  2. 請求完成有結果了之后,將請求的回調函數(shù)添加到任務隊列中,等待 JS 引擎處理。

 

JavaScript 引擎是單線程

JavaScript 引擎是單線程,也就是說每次只能執(zhí)行一項任務,其他任務都得按照順序排隊等待被執(zhí)行,只有當前的任務執(zhí)行完成之后才會往下執(zhí)行下一個任務。

HTML5 中提出了 Web-Worker API,主要是為了解決頁面阻塞問題,但是并沒有改變 JavaScript 是單線程的本質。了解 Web-Worker。

JavaScript 事件循環(huán)機制

JavaScript 事件循環(huán)機制分為瀏覽器和 Node 事件循環(huán)機制,兩者的實現(xiàn)技術不一樣,瀏覽器 Event Loop 是 HTML 中定義的規(guī)范,Node Event Loop 是由 libuv 庫實現(xiàn)。這里主要講的是瀏覽器部分。

Javascript 有一個 main thread 主線程和 call-stack 調用棧(執(zhí)行棧),所有的任務都會被放到調用棧等待主線程執(zhí)行。

JS 調用棧

JS 調用棧是一種后進先出的數(shù)據(jù)結構。當函數(shù)被調用時,會被添加到棧中的頂部,執(zhí)行完成之后就從棧頂部移出該函數(shù),直到棧內被清空。

同步任務、異步任務

JavaScript 單線程中的任務分為同步任務和異步任務。同步任務會在調用棧中按照順序排隊等待主線程執(zhí)行,異步任務則會在異步有了結果后將注冊的回調函數(shù)添加到任務隊列(消息隊列)中等待主線程空閑的時候,也就是棧內被清空的時候,被讀取到棧中等待主線程執(zhí)行。任務隊列是先進先出的數(shù)據(jù)結構。

Event Loop

調用棧中的同步任務都執(zhí)行完畢,棧內被清空了,就代表主線程空閑了,這個時候就會去任務隊列中按照順序讀取一個任務放入到棧中執(zhí)行。每次棧內被清空,都會去讀取任務隊列有沒有任務,有就讀取執(zhí)行,一直循環(huán)讀取-執(zhí)行的操作,就形成了事件循環(huán)。

定時器

定時器會開啟一條定時器觸發(fā)線程來觸發(fā)計時,定時器會在等待了指定的時間后將事件放入到任務隊列中等待讀取到主線程執(zhí)行。

定時器指定的延時毫秒數(shù)其實并不準確,因為定時器只是在到了指定的時間時將事件放入到任務隊列中,必須要等到同步的任務和現(xiàn)有的任務隊列中的事件全部執(zhí)行完成之后,才會去讀取定時器的事件到主線程執(zhí)行,中間可能會存在耗時比較久的任務,那么就不可能保證在指定的時間執(zhí)行。

宏任務(macro-task)、微任務(micro-task)

除了廣義的同步任務和異步任務,JavaScript 單線程中的任務可以細分為宏任務和微任務。

macro-task包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。

micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver。

console.log(1);
setTimeout(function() {
  console.log(2);
})
var promise = new Promise(function(resolve, reject) {
  console.log(3);
  resolve();
})
promise.then(function() {
  console.log(4);
})
console.log(5);

示例中,setTimeout 和 Promise被稱為任務源,來自不同的任務源注冊的回調函數(shù)會被放入到不同的任務隊列中。

有了宏任務和微任務的概念后,那 JS 的執(zhí)行順序是怎樣的?是宏任務先還是微任務先?

第一次事件循環(huán)中,JavaScript 引擎會把整個 script 代碼當成一個宏任務執(zhí)行,執(zhí)行完成之后,再檢測本次循環(huán)中是否尋在微任務,存在的話就依次從微任務的任務隊列中讀取執(zhí)行完所有的微任務,再讀取宏任務的任務隊列中的任務執(zhí)行,再執(zhí)行所有的微任務,如此循環(huán)。JS 的執(zhí)行順序就是每次事件循環(huán)中的宏任務-微任務。

  1. 上面的示例中,第一次事件循環(huán),整段代碼作為宏任務進入主線程執(zhí)行。
  2. 遇到了 setTimeout ,就會等到過了指定的時間后將回調函數(shù)放入到宏任務的任務隊列中。
  3. 遇到 Promise,將 then 函數(shù)放入到微任務的任務隊列中。
  4. 整個事件循環(huán)完成之后,會去檢測微任務的任務隊列中是否存在任務,存在就執(zhí)行。
  5. 第一次的循環(huán)結果打印為: 1,3,5,4。
  6. 接著再到宏任務的任務隊列中按順序取出一個宏任務到棧中讓主線程執(zhí)行,那么在這次循環(huán)中的宏任務就是 setTimeout 注冊的回調函數(shù),執(zhí)行完這個回調函數(shù),發(fā)現(xiàn)在這次循環(huán)中并不存在微任務,就準備進行下一次事件循環(huán)。
  7. 檢測到宏任務隊列中已經(jīng)沒有了要執(zhí)行的任務,那么就結束事件循環(huán)。
  8. 最終的結果就是 1,3,5,4,2。

以上所述是小編給大家介紹的JS瀏覽器事件循環(huán)機制詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • Typescript中的as、問號與感嘆號詳解

    Typescript中的as、問號與感嘆號詳解

    這篇文章主要介紹了Typescript中的as、問號與感嘆號詳解,本文分別講述了這幾個關鍵字的含義作用以及實例,通過文字和代碼的描述,詳細的表達.以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • 在JavaScript中使用開平方根的sqrt()方法

    在JavaScript中使用開平方根的sqrt()方法

    這篇文章主要介紹了在JavaScript中使用開平方根的sqrt()方法,是JS入門學習中的基礎知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript 基礎問答一

    JavaScript 基礎問答一

    今天在網(wǎng)上看到了一份很不錯的JavaScript FAQ,由于擔心自己并不能一直把它讀完,所以就嘗試翻譯一些內容,和朋友們一起分享。
    2008-12-12
  • js導航菜單(自寫)簡單大方

    js導航菜單(自寫)簡單大方

    一個簡單的多級下拉菜單菜單但是由于業(yè)務和樣式上的要求,為了簡潔找了好多都不適合于是自己寫了一個,曬出來與大家分享,感興趣的朋友可以參考下哈,希望可以幫助到你
    2013-03-03
  • 特殊數(shù)據(jù)的js四舍五入問題

    特殊數(shù)據(jù)的js四舍五入問題

    特殊數(shù)據(jù)的js四舍五入問題...
    2007-02-02
  • js正則相關知識點專題

    js正則相關知識點專題

    本篇內容是小編整理的關于腳本之家精選的JS正則的優(yōu)秀文章,適合大家學習JS正則的相關內容,有需要的朋友參考下。
    2018-05-05
  • ES6學習總結之Set和Map的使用

    ES6學習總結之Set和Map的使用

    這篇博客介紹了 ES6 中的 Set 和 Map 數(shù)據(jù)結構,Set 是一個存儲唯一值的集合,支持添加、刪除、檢查元素的方法,Map 則是用于存儲鍵值對的集合,鍵和值都可以是任何類型,文章詳細講解了兩者的主要方法和用法,并與傳統(tǒng)的數(shù)組和對象進行了對比,突出 Set 和 Map 的獨特優(yōu)勢
    2024-08-08
  • 簡單介紹JavaScript的變量和數(shù)據(jù)類型

    簡單介紹JavaScript的變量和數(shù)據(jù)類型

    這篇文章主要介紹了簡單介紹JavaScript的變量和數(shù)據(jù)類型,是JS入門中的基礎知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript中的6種運算符總結

    JavaScript中的6種運算符總結

    這篇文章主要介紹了JavaScript中的6種運算符總結,本文總結了算術運算符、賦值運算符、比較運算符、三元運算符、邏輯運算符、字符串連接運算符等,需要的朋友可以參考下
    2014-10-10
  • 深入理解JavaScript系列(44):設計模式之橋接模式詳解

    深入理解JavaScript系列(44):設計模式之橋接模式詳解

    這篇文章主要介紹了深入理解JavaScript系列(44):設計模式之橋接模式詳解,橋接模式(Bridge)將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化,需要的朋友可以參考下
    2015-03-03

最新評論