亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

改變你對(duì)事件循環(huán)錯(cuò)誤的認(rèn)知!

freeflydom
2023年8月28日 9:28 本文熱度 1579

瀏覽器的進(jìn)程模型

何為進(jìn)程?

  • 程序運(yùn)行需要有它自己的內(nèi)存空間,可以把這塊內(nèi)存空間簡單的理解為進(jìn)程。

  • 每個(gè)應(yīng)用至少有一個(gè)進(jìn)程,進(jìn)程之間相互獨(dú)立,即使要通訊,也需要雙方同意

何為線程?

  • 一個(gè)進(jìn)程至少有一個(gè)線程,進(jìn)程開啟后會(huì)自動(dòng)創(chuàng)建一個(gè)線程來運(yùn)行代碼,這個(gè)線程叫主線程,主線程結(jié)束,則進(jìn)程結(jié)束。

  • 如果程序想同時(shí)執(zhí)行多塊代碼,主線程會(huì)啟動(dòng)更多的線程來執(zhí)行代碼,所以一個(gè)進(jìn)程可以有多個(gè)線程。

瀏覽器有哪些進(jìn)程和線程?

瀏覽器是一個(gè)多進(jìn)程多線程的應(yīng)用程序

  • 為了避免相互影響,減少連環(huán)崩潰的幾率,他會(huì)自動(dòng)啟動(dòng)多個(gè)進(jìn)程。

瀏覽器右上角三個(gè)點(diǎn)那里的更多工具打開任務(wù)管理器:

每打開一個(gè)標(biāo)簽頁就會(huì)開啟一個(gè)渲染線程,嘗試多打開一個(gè)標(biāo)簽頁,任務(wù)管理器會(huì)多一個(gè)線程。

  • 主要有下面三個(gè):

  • 瀏覽器進(jìn)程:主要負(fù)責(zé)界面顯示(是指瀏覽器窗體那些界面的交互,而非標(biāo)簽頁面內(nèi)容),用戶交互、子進(jìn)程管理等,瀏覽器進(jìn)程內(nèi)部會(huì)啟動(dòng)多個(gè)線程處理不同的任務(wù)。

  • 網(wǎng)絡(luò)進(jìn)程 負(fù)責(zé)加載網(wǎng)絡(luò)資源,網(wǎng)絡(luò)進(jìn)程內(nèi)部會(huì)啟動(dòng)多個(gè)線程處理不同的任務(wù)。

  • 渲染進(jìn)程

    • 渲染進(jìn)程啟動(dòng)后,會(huì)開啟一個(gè)渲染主線程,主線程負(fù)責(zé)執(zhí)行 HTML、CSS、JS 代碼

    • 默認(rèn)情況下,瀏覽器會(huì)為每個(gè)標(biāo)簽頁開啟一個(gè)新的渲染進(jìn)程,以保證不同的標(biāo)簽頁之前不互相影響(以后瀏覽器可能會(huì)改變這種方式,為了減少進(jìn)程的數(shù)量,在尋求的方案比如一個(gè)站點(diǎn)開辟一個(gè)進(jìn)程)

渲染主線程是如何工作的?

渲染主線程是瀏覽器中最繁忙的的線程,需要它處理的任務(wù)包括但不限于:

  • 解析 HTMl

  • 解析 CSS

  • 計(jì)算樣式

  • 布局

  • 處理圖層

  • 每秒把頁面畫60次(FPS)

  • 執(zhí)行全局 JS 代碼

  • 執(zhí)行事件處理函數(shù)

  • 執(zhí)行計(jì)時(shí)器的回調(diào)函數(shù)

  • ......

為何只能有一個(gè)渲染主線程?比如正在執(zhí)行一個(gè)js函數(shù)去修改頁面,定時(shí)器的任務(wù)也到達(dá)了時(shí)間,那么應(yīng)該執(zhí)行哪個(gè)?同時(shí)執(zhí)行的話,修改了同一個(gè)地方如何選擇。

一個(gè)渲染進(jìn)程只能有一個(gè)渲染主進(jìn)程,使用消息隊(duì)列來調(diào)度任務(wù)

  • 在最開始的時(shí)候、渲染主線程會(huì)進(jìn)入一個(gè)無限循環(huán)

  • 每一次循環(huán)會(huì)檢查消息隊(duì)列中是否有任務(wù)存在,如果有,就取出第一個(gè)任務(wù)執(zhí)行,執(zhí)行完一個(gè)后進(jìn)入下一次循環(huán),如果沒有,則進(jìn)入休眠狀態(tài)

  • 其它所有線程(包括其它進(jìn)程的線程,比如點(diǎn)擊事件,計(jì)時(shí)器的回調(diào)函數(shù)等)可以隨時(shí)向消息隊(duì)列添加任務(wù)。新任務(wù)會(huì)加到消息隊(duì)列的末尾。在添加新任務(wù)時(shí),如果主線程是休眠狀態(tài),則會(huì)將其喚醒以繼續(xù)拿取任務(wù)執(zhí)行。

若干解釋

何為異步?

代碼執(zhí)行過程中,會(huì)遇到一些無法立即執(zhí)行的任務(wù),比如:

  • 計(jì)時(shí)完成后需要執(zhí)行的任務(wù) -- setTimeout、setInterval

  • 網(wǎng)絡(luò)通訊完成后需要執(zhí)行的任務(wù) -- XHR、Fetch

  • 用戶操作后需要執(zhí)行的任務(wù) -- addEventListener

面試題:如何理解 JS 的異步?

Js 是一門單線程的語言,這是因?yàn)樗\(yùn)行在瀏覽器的渲染主線程中,而渲染主線程只有一個(gè)。
渲染主線程承擔(dān)著諸多任務(wù),比如渲染頁面、執(zhí)行 JS 、解析 CSS
如果使用同步的方式,就極有可能會(huì)導(dǎo)致主線程的阻塞,從而導(dǎo)致消息隊(duì)列的很多其它任務(wù)無法執(zhí)行,頁面無法及時(shí)更新,給用戶造成卡死現(xiàn)象。
所以瀏覽器使用異步的方式避免,具體做法是當(dāng)某些任務(wù)發(fā)生時(shí),比如計(jì)時(shí)器、網(wǎng)絡(luò)、事件監(jiān)聽,主線程將任務(wù)交給其它線程處理,自身立即結(jié)束此任務(wù)的執(zhí)行,轉(zhuǎn)而執(zhí)行后續(xù)代碼。當(dāng)其它線程完成此任務(wù)時(shí),將事先傳遞的回調(diào)函數(shù)包裝成任務(wù),加入到消息隊(duì)列的末尾排隊(duì),等待主線程的調(diào)度執(zhí)行。
在這種異步模式下,瀏覽器永不阻塞,從而最大限度的保證了單線程的流暢執(zhí)行。

js 為何會(huì)阻礙渲染?

渲染主線程只有一個(gè),js 的執(zhí)行與渲染都在主線程中,兩者無法同時(shí)執(zhí)行。react 的fiber 就是為了解決此問題

任務(wù)有優(yōu)先級(jí)嗎?

任務(wù)沒有優(yōu)先級(jí),消息隊(duì)列有優(yōu)先級(jí),消息隊(duì)列會(huì)有多種,隨著瀏覽器的復(fù)雜度急劇提升,W3C 將不再使用宏隊(duì)列的說法

根據(jù) W3C 的最新解釋:

  • 每個(gè)任務(wù)都有一個(gè)任務(wù)類型,同一個(gè)類型的任務(wù)必須在一個(gè)隊(duì)列,不同類型的任務(wù)可以分屬于不同的隊(duì)列

  • 瀏覽器必須準(zhǔn)備好一個(gè)微隊(duì)列,微隊(duì)列中的任務(wù)優(yōu)先所有其它任務(wù)執(zhí)行

在目前 chrome 的實(shí)現(xiàn)中,至少包含了下面隊(duì)列, 微隊(duì)列 > 交互隊(duì)列 > 延時(shí)隊(duì)列

  • 微隊(duì)列:用戶存放需要最快執(zhí)行的任務(wù),優(yōu)先級(jí)最高 (Promise、MutationObserver)

  • 交互隊(duì)列:用戶存放用戶操作后產(chǎn)生的事件處理任務(wù),瀏覽器認(rèn)為用戶的操作必須及時(shí)響應(yīng),優(yōu)先級(jí)高 (addEventListener)

  • 延時(shí)隊(duì)列:用戶存放計(jì)時(shí)器到達(dá)后的回調(diào)任務(wù),優(yōu)先級(jí)中 (setTimeout、setInterval)

幾道題加深理解

setTimeout(()=>{

    console.log(1) // 交給計(jì)時(shí)線程,等待添加到延時(shí)隊(duì)列

},0)

console.log(2)  // 執(zhí)行完后執(zhí)行延時(shí)隊(duì)列中的任務(wù)


結(jié)果:輸入 2,1


function delay(duration){

    var start = Date.now();

    while (Date.now() - start < duration){}

}


setTimeout(()=>{

    console.log(1) // 交給計(jì)時(shí)線程,等待添加到延時(shí)隊(duì)列

},0)


delay(1000) // 阻塞主線程一秒

 

console.log(2) // 輸出 2,由于阻塞一秒后,計(jì)時(shí)線程已經(jīng)把任務(wù)計(jì)時(shí)完成加到延時(shí)隊(duì)列了,所以輸出 2 后立即輸出 1


結(jié)果:等待一秒后,同時(shí)輸出 2,1 


setTimeout(()=>{

    console.log(1) // 交給計(jì)時(shí)線程,等待添加到延時(shí)隊(duì)列

},0)


Promise.resolve().then(()=>{

    console.log(2)  // 立即添加到微隊(duì)列,微隊(duì)列優(yōu)先級(jí)高于延時(shí)隊(duì)列

})


console.log(3)  // 全局任務(wù)


結(jié)果:輸出 3,2,1


// 只是定義,還未執(zhí)行哈

function a(){

    console.log(1)

    Promise.resolve().then(()=>{

     console.log(2)  

    })

}


setTimeout(()=>{

    console.log(3)

    Promise.resolve().then(a)

},0)


Promise.resolve().then(()=>{

     console.log(4)  // 立即添加到微隊(duì)列,微隊(duì)列優(yōu)先級(jí)高于延時(shí)隊(duì)列

})


console.log(5) // 全局


結(jié)果:5,4,3,1,2


總結(jié)

什么是事件循環(huán)?

  • 事件循環(huán)又叫消息循環(huán),是瀏覽器渲染主線程的工作方式

  • 在 Chrome 的源碼中,它會(huì)開啟一個(gè)不會(huì)結(jié)束的 for 循環(huán),每次循環(huán)從消息隊(duì)列中取出第一個(gè)任務(wù)執(zhí)行,其它線程只需要在合適的時(shí)候?qū)⑷蝿?wù)加到隊(duì)列末尾即可

  • 過去把消息隊(duì)列簡單分為宏隊(duì)列和微隊(duì)列,這種說法目前已無法滿足復(fù)雜的瀏覽器環(huán)境,取而代之的是一種更加靈活多變的方式:

    • 根據(jù) W3C 官方的解釋,每個(gè)任務(wù)有不同的類型,同類型的任務(wù)必須在同一個(gè)隊(duì)列,不同任務(wù)可以屬于不同隊(duì)列。

    • 不同任務(wù)有不同的優(yōu)先級(jí),在一次事件循環(huán)中,由瀏覽器自行決定取哪個(gè)隊(duì)列的任務(wù)。

    • 但瀏覽器必須有一個(gè)微隊(duì)列,微隊(duì)列的任務(wù)一定具有最高的優(yōu)先級(jí),必須優(yōu)先調(diào)度執(zhí)行。

JS 中的計(jì)時(shí)器能做到精確計(jì)時(shí)嗎?

不行,因?yàn)?/p>

  • 計(jì)算機(jī)硬件沒有原子鐘,無法做到精確計(jì)時(shí)

  • 操作系統(tǒng)的計(jì)時(shí)函數(shù)本身就有少量偏差,由于 JS 的計(jì)時(shí)器最終調(diào)用的是操作系統(tǒng)的函數(shù),也就攜帶了這些偏差

  • 按照 W3C 的標(biāo)準(zhǔn),瀏覽器實(shí)現(xiàn)計(jì)時(shí)器時(shí),如果嵌套層級(jí)超過 5 層,則會(huì)帶有 4 毫秒的最少時(shí)間,這樣在計(jì)時(shí)時(shí)間少于 4 毫秒又帶來了偏差

  • 受事件循環(huán)的影響,計(jì)時(shí)器的回調(diào)函數(shù)只能在主線程空閑時(shí)運(yùn)行,時(shí)間到了也未必會(huì)立即執(zhí)行,所以又帶了偏差


結(jié)語:單線程是異步產(chǎn)生的原因,事件循環(huán)是異步的實(shí)現(xiàn)方式


查看原文



該文章在 2023/8/28 9:28:08 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved