国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Event Loop

darkbug / 1707人閱讀

摘要:引擎線程,也稱為內(nèi)核,負(fù)責(zé)處理腳本程序,例如引擎。異步請求線程,也就是發(fā)出請求后,接收響應(yīng)檢測狀態(tài)變更等都是這個線程管理的。為了解決這個問題,提出標(biāo)準(zhǔn),允許腳本創(chuàng)建多個線程,但是子線程完全受主線程控制,且不得操作。

本文主要參閱了以下兩篇文章,對JS的Event Loop運(yùn)行機(jī)制基礎(chǔ)知識進(jìn)行了整理。
從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制最全面的一次梳理
JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop

背景知識 進(jìn)程與線程

大家都知道JavaScript是單線程的,這就引申出一個問題,進(jìn)程與線程是什么,他們的區(qū)別是什么?
先給出進(jìn)程和線程的定義:

進(jìn)程是cpu資源分配的最小單位(是能擁有資源和獨(dú)立運(yùn)行的最小單位)

線程是cpu調(diào)度的最小單位(線程是建立在進(jìn)程的基礎(chǔ)上的一次程序運(yùn)行單位,一個進(jìn)程中可以有多個線程)

用工廠和工人的例子來形象闡述:

- 進(jìn)程是一個工廠,工廠有它的獨(dú)立資源 -> 系統(tǒng)分配的內(nèi)存(獨(dú)立的一塊內(nèi)存)

- 工廠之間相互獨(dú)立 -> 進(jìn)程之間相互獨(dú)立

- 線程是工廠中的工人,多個工人協(xié)作完成任務(wù) -> 多個線程在進(jìn)程中協(xié)作完成任務(wù)

- 工廠內(nèi)有一個或多個工人 -> 一個進(jìn)程由一個或多個線程組成

- 工人之間共享工廠的資源 -> 同一進(jìn)程下的各個線程之間共享進(jìn)程的內(nèi)存空間(包括代碼段、數(shù)據(jù)集、堆等)

補(bǔ)充:

我們所說的單線程和多線程,是指一個進(jìn)程內(nèi)是單一線程還是多線程。

進(jìn)程間的通信方式包括: 管道pipe、 命名管道FIFO、消息隊(duì)列MessageQueue、共享存儲SharedMemory、信號量Semaphore、套接字Socket、信號。

瀏覽器是多進(jìn)程的

關(guān)于瀏覽器進(jìn)程問題可以簡單基礎(chǔ)三點(diǎn):

瀏覽器是多進(jìn)程的。

瀏覽器之所以能夠運(yùn)行,是因?yàn)橄到y(tǒng)給它的進(jìn)程分配了資源(cpu、內(nèi)存)。

簡單點(diǎn)理解,每打開一個Tab頁,就相當(dāng)于創(chuàng)建了一個獨(dú)立的瀏覽器進(jìn)程。

平時 coding 接觸到最多的一個瀏覽器進(jìn)程是瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核),它管理著頁面渲染。腳本執(zhí)行,事件處理等。要同時處理這么多事情,渲染進(jìn)程顯然是多線程的,它主要包括以下5個常駐線程:

GUI渲染線程,負(fù)責(zé)渲染瀏覽器界面,解析HTML,CSS,構(gòu)建DOM樹和RenderObject樹,布局和繪制等。

JS引擎線程,也稱為JS內(nèi)核,負(fù)責(zé)處理Javascript腳本程序,(例如V8引擎)。

事件觸發(fā)線程,用來控制事件循環(huán)(可以理解為,JS引擎線程自己都忙不過來,需要瀏覽器另開線程協(xié)助)。

定時觸發(fā)器線程,瀏覽器定時計數(shù)器并不是由JavaScript引擎計數(shù)的,(因?yàn)镴avaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會影響記計時的準(zhǔn)確),JS中常用的setIntervalsetTimeout就歸這個線程管理。

異步http請求線程,也就是ajax發(fā)出http請求后,接收響應(yīng)、檢測狀態(tài)變更等都是這個線程管理的。

我們常說的JavaScript是單線程的,其實(shí)就是說的JS引擎是單線程的,它僅僅是瀏覽器渲染進(jìn)程種的一個線程。為什么呢?因?yàn)镴avaScript的主要作用是與用戶互動,以及操作DOM,如果JavaScript有兩個線程,一個線程對一個DOM節(jié)點(diǎn)執(zhí)行 A 操作,另一個線程這個DOM節(jié)點(diǎn)執(zhí)行 B 操作,那么就會起沖突,所以JavaScript在前端的應(yīng)用就注定了它是單線程的。

然而JavaScript的單線程特性就注定我們不用它去完成密集的 cpu 運(yùn)算,因?yàn)槊芗?cpu 運(yùn)算耗時過長,阻塞頁面渲染。為了解決這個問題,HTML5提出 Web Worker 標(biāo)準(zhǔn),允許JavaScript腳本創(chuàng)建多個線程,但是子線程完全受主線程控制,且不得操作DOM

Event Loop

JavaScript 是單線程的帶來的問題是:所有任務(wù)都必須同步執(zhí)行,問題就出現(xiàn)了,很多 I/O 過程是非常耗時的(如http 請求數(shù)據(jù)),如果要等到 I/O 過程結(jié)束再執(zhí)行后續(xù)任務(wù),就會出現(xiàn)頁面的卡頓、cpu 的閑置。于是異步的任務(wù)就出現(xiàn)了,異步任務(wù)是指掛起處于等待中的任務(wù),繼續(xù)執(zhí)行同步任務(wù),等到結(jié)果返回再去繼續(xù)執(zhí)行被掛起的任務(wù)。于是,JavaScript 的任務(wù)可以分為同步任務(wù)和異步任務(wù)。下面就引出 Event Loop 機(jī)制:

所有同步任務(wù)都在主線程上執(zhí)行,形成一個執(zhí)行棧

主線程之外,事件觸發(fā)線程管理著一個任務(wù)隊(duì)列,只要異步任務(wù)有了運(yùn)行結(jié)果,就在任務(wù)隊(duì)列之中放置一個事件。

一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢(此時JS引擎空閑),系統(tǒng)就會讀取任務(wù)隊(duì)列,將可運(yùn)行的異步任務(wù)添加到執(zhí)行棧中,開始執(zhí)行。

如上圖所示,執(zhí)行棧中的代碼會調(diào)用一個異步的API,它們會在任務(wù)隊(duì)列中添加各種事件(或者說回調(diào)函數(shù)),另外用戶的操作如clickmousedown等都會在任務(wù)隊(duì)列中添加事件。只要執(zhí)行棧中的代碼執(zhí)行完畢,主線程就會去讀取任務(wù)隊(duì)列,將可執(zhí)行的回調(diào)函數(shù)放到執(zhí)行棧中執(zhí)行。

總結(jié)一下:

執(zhí)行棧執(zhí)行完畢 -> 主線程讀取任務(wù)隊(duì)列,并執(zhí)行回調(diào)函數(shù) -> 執(zhí)行棧執(zhí)行完畢 -> 主線程讀取任務(wù)隊(duì)列,并執(zhí)行回調(diào)函數(shù) ...

這個過程一直循環(huán)下去,所以就叫事件循環(huán)(Event Loop)。

setTimeout 和 setInterval

前面提到了瀏覽器的定時觸發(fā)器線程,它的主要作用就是計時,setTimeoutsetInterval 就由它來控制,原理就是到達(dá)設(shè)置時間后,往任務(wù)隊(duì)列中添加這兩個函數(shù)中指定的回調(diào)函數(shù)。

setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計算表達(dá)式。但是需要注意的是,實(shí)際是計時結(jié)束后定時觸發(fā)器線程才會將回調(diào)函數(shù)放到任務(wù)隊(duì)列中去,此時任務(wù)隊(duì)列中這個回調(diào)之前可能已經(jīng)有一些事件待處理,并且一定要執(zhí)行棧的任務(wù)執(zhí)行完后才會開始執(zhí)行任務(wù)隊(duì)列中的任務(wù),所以 setTimeout() 中回調(diào)開始執(zhí)行的時間是:執(zhí)行棧執(zhí)行時間 + 任務(wù)隊(duì)列前方回調(diào)執(zhí)行時間 + 延遲時間

setInterval() 方法可按照指定的時間間隔來周期性調(diào)用函數(shù)或計算表達(dá)式。它的問題在于:每次都精確的隔一段時間將一個回調(diào)放到任務(wù)隊(duì)列中,并沒有考慮到內(nèi)部回調(diào)函數(shù)執(zhí)行所需時間,這就會導(dǎo)致兩種問題:

回調(diào)函數(shù)執(zhí)行需要時間,兩個函數(shù)執(zhí)行的時間間隔會小于設(shè)定值;

如果回調(diào)函數(shù)執(zhí)行時間大于設(shè)定間隔,就會出現(xiàn)上一個加入任務(wù)隊(duì)列中的回調(diào)還沒執(zhí)行完,下一個回調(diào)就被加入任務(wù)隊(duì)列了,就會出現(xiàn)累計效應(yīng),即后面的回調(diào)會連續(xù)執(zhí)行。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96459.html

相關(guān)文章

  • event loop規(guī)范探究javaScript異步及瀏覽器更新渲染時機(jī)

    摘要:規(guī)范中定義了瀏覽器何時進(jìn)行渲染更新,了解它有助于性能優(yōu)化。結(jié)合一些資料,對上邊規(guī)范給出一些理解有誤請指正每個線程都有自己的。列為,列為,列為。我們都知道是單線程,渲染計算和腳本運(yùn)行共用同一線程網(wǎng)絡(luò)請求會有其他線程,導(dǎo)致腳本運(yùn)行會阻塞渲染。 本文轉(zhuǎn)自blog 轉(zhuǎn)載請注明出處 異步的思考 event loops隱藏得比較深,很多人對它很陌生。但提起異步,相信每個人都知道。異步背后的靠山就是...

    13651657101 評論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個例子其實(shí)是在這個中找到的,第一個使用的版本是,這個版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠校谑怯扔晗牧藢?shí)現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對于event loop 可以抽象成一段簡單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    springDevBird 評論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個例子其實(shí)是在這個中找到的,第一個使用的版本是,這個版本的實(shí)現(xiàn)是采用了,而后因?yàn)榈睦锏挠校谑怯扔晗牧藢?shí)現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調(diào)放入的隊(duì)列。 結(jié)論 對于event loop 可以抽象成一段簡單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    Barry_Ng 評論0 收藏0
  • JavaScript 事件循環(huán)(譯文JavaScript Event Loop

    摘要:事件循環(huán)了解了在引擎中是如何工作了之后,來看下如何使用異步回調(diào)函數(shù)來避免代碼。從回調(diào)函數(shù)被放入后秒鐘,把移到中。由于事件循環(huán)持續(xù)地監(jiān)測調(diào)用棧是否已空,此時它一注意到調(diào)用棧空了,就調(diào)用并創(chuàng)建一個新的調(diào)用棧。 聽多了JavaScript單線程,異步,V8,便會很想去知道JavaScript是如何利用單線程來實(shí)現(xiàn)所謂的異步的。我參考了一些文章,了解到一個很重要的詞匯:事件循環(huán)(Event L...

    K_B_Z 評論0 收藏0
  • Javascript 運(yùn)行機(jī)制詳解,Event Loop

    摘要:主線程在任務(wù)隊(duì)列中讀取事件,這個過程是循環(huán)不斷地,所以這種運(yùn)行機(jī)制叫做事件循環(huán)是在執(zhí)行棧同步代碼結(jié)束之后,下一次任務(wù)隊(duì)列執(zhí)行之前。 單線程 javascript為什么是單線程語言,原因在于如果是多線程,當(dāng)一個線程對DOM節(jié)點(diǎn)做添加內(nèi)容操作的時候,另一個線程要刪除這個DOM節(jié)點(diǎn),這個時候,瀏覽器應(yīng)該怎么選擇,這就造成了混亂,為了解決這類問題,在一開始的時候,javascript就采用單線...

    Jingbin_ 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<