欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

JS中瀏覽器事件循環(huán)機(jī)制的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)JS中瀏覽器事件循環(huán)機(jī)制的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)北侖免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

先來明白些概念性內(nèi)容。

進(jìn)程、線程

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

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

瀏覽器內(nèi)核

瀏覽器是多進(jìn)程的,瀏覽器每一個 tab 標(biāo)簽都代表一個獨(dú)立的進(jìn)程(也不一定,因?yàn)槎鄠€空白 tab 標(biāo)簽會合并成一個進(jìn)程),瀏覽器內(nèi)核(瀏覽器渲染進(jìn)程)屬于瀏覽器多進(jìn)程中的一種。

瀏覽器內(nèi)核有多種線程在工作。

GUI 渲染線程:

  1. 負(fù)責(zé)渲染頁面,解析 HTML,CSS 構(gòu)成 DOM 樹等,當(dāng)頁面重繪或者由于某種操作引起回流都會調(diào)起該線程。

  2. 和 JS 引擎線程是互斥的,當(dāng) JS 引擎線程在工作的時候,GUI 渲染線程會被掛起,GUI 更新被放入在 JS 任務(wù)隊(duì)列中,等待 JS 引擎線程空閑的時候繼續(xù)執(zhí)行。

JS 引擎線程:

  1. 單線程工作,負(fù)責(zé)解析運(yùn)行 JavaScript 腳本。

  2. 和 GUI 渲染線程互斥,JS 運(yùn)行耗時過長就會導(dǎo)致頁面阻塞。

事件觸發(fā)線程:

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

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

  1. 瀏覽器定時計數(shù)器并不是由 JS 引擎計數(shù)的,阻塞會導(dǎo)致計時不準(zhǔn)確。

  2. 開啟定時器觸發(fā)線程來計時并觸發(fā)計時,計時完成后會被添加到任務(wù)隊(duì)列中,等待 JS 引擎處理。

http 請求線程:

  1. http 請求的時候會開啟一條請求線程。

  2. 請求完成有結(jié)果了之后,將請求的回調(diào)函數(shù)添加到任務(wù)隊(duì)列中,等待 JS 引擎處理。

 JS中瀏覽器事件循環(huán)機(jī)制的示例分析

JavaScript 引擎是單線程

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

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

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

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

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

JS 調(diào)用棧

JS 調(diào)用棧是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。當(dāng)函數(shù)被調(diào)用時,會被添加到棧中的頂部,執(zhí)行完成之后就從棧頂部移出該函數(shù),直到棧內(nèi)被清空。

同步任務(wù)、異步任務(wù)

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

Event Loop

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

JS中瀏覽器事件循環(huán)機(jī)制的示例分析

JS中瀏覽器事件循環(huán)機(jī)制的示例分析

定時器

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

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

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

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

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被稱為任務(wù)源,來自不同的任務(wù)源注冊的回調(diào)函數(shù)會被放入到不同的任務(wù)隊(duì)列中。

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

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

  1. 上面的示例中,第一次事件循環(huán),整段代碼作為宏任務(wù)進(jìn)入主線程執(zhí)行。

  2. 遇到了 setTimeout ,就會等到過了指定的時間后將回調(diào)函數(shù)放入到宏任務(wù)的任務(wù)隊(duì)列中。

  3. 遇到 Promise,將 then 函數(shù)放入到微任務(wù)的任務(wù)隊(duì)列中。

  4. 整個事件循環(huán)完成之后,會去檢測微任務(wù)的任務(wù)隊(duì)列中是否存在任務(wù),存在就執(zhí)行。

  5. 第一次的循環(huán)結(jié)果打印為: 1,3,5,4。

  6. 接著再到宏任務(wù)的任務(wù)隊(duì)列中按順序取出一個宏任務(wù)到棧中讓主線程執(zhí)行,那么在這次循環(huán)中的宏任務(wù)就是 setTimeout 注冊的回調(diào)函數(shù),執(zhí)行完這個回調(diào)函數(shù),發(fā)現(xiàn)在這次循環(huán)中并不存在微任務(wù),就準(zhǔn)備進(jìn)行下一次事件循環(huán)。

  7. 檢測到宏任務(wù)隊(duì)列中已經(jīng)沒有了要執(zhí)行的任務(wù),那么就結(jié)束事件循環(huán)。

  8. 最終的結(jié)果就是 1,3,5,4,2。

關(guān)于“JS中瀏覽器事件循環(huán)機(jī)制的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

網(wǎng)站題目:JS中瀏覽器事件循環(huán)機(jī)制的示例分析
網(wǎng)頁網(wǎng)址:http://chinadenli.net/article20/ppcjco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化企業(yè)網(wǎng)站制作、定制網(wǎng)站面包屑導(dǎo)航、全網(wǎng)營銷推廣、外貿(mào)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)
日韩午夜老司机免费视频| 欧美成人欧美一级乱黄| 精品女同在线一区二区| 婷婷九月在线中文字幕| 麻豆一区二区三区在线免费| 极品熟女一区二区三区| 老司机精品一区二区三区| 小黄片大全欧美一区二区| 亚洲av成人一区二区三区在线| 欧美三级不卡在线观线看| 97人妻精品免费一区二区| 免费一区二区三区少妇| 亚洲成人精品免费在线观看| 亚洲精品偷拍视频免费观看| 成人午夜视频在线播放| 五月天丁香婷婷狠狠爱| 国产麻豆成人精品区在线观看| 亚洲夫妻性生活免费视频| 国产精品熟女乱色一区二区| 日本本亚洲三级在线播放| 日韩中文无线码在线视频| 日本不卡视频在线观看| 美国欧洲日本韩国二本道| 精品偷拍一区二区三区| 偷拍洗澡一区二区三区| 欧美日韩国产精品黄片| 大香蕉久久精品一区二区字幕| 国产午夜免费在线视频| 国产精品日本女优在线观看| 日本婷婷色大香蕉视频在线观看| 中文字幕人妻综合一区二区| 亚洲男人的天堂久久a| 中文字幕人妻日本一区二区| 国产成人精品午夜福利av免费| 国产精品自拍杆香蕉视频| 欧美日韩中国性生活视频| 国产成人国产精品国产三级 | 日韩免费av一区二区三区| 久久青青草原中文字幕| 丝袜视频日本成人午夜视频 | 91午夜少妇极品福利|