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

資訊專欄INFORMATION COLUMN

10分鐘理解JS引擎的執(zhí)行機(jī)制

zzbo / 2430人閱讀

摘要:深入理解引擎的執(zhí)行機(jī)制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實(shí)現(xiàn)異步的呢中的中的說說首先請(qǐng)牢記點(diǎn)是單線程語(yǔ)言的是的執(zhí)行機(jī)制。

深入理解JS引擎的執(zhí)行機(jī)制

1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實(shí)現(xiàn)異步的呢?

2.JS中的event loop(1)

3.JS中的event loop(2)

4.說說setTimeout

首先,請(qǐng)牢記2點(diǎn):

(1) JS是單線程語(yǔ)言

(2) JS的Event Loop是JS的執(zhí)行機(jī)制。深入了解JS的執(zhí)行,就等于深入了解JS里的event loop

1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實(shí)現(xiàn)異步的呢?

技術(shù)的出現(xiàn),都跟現(xiàn)實(shí)世界里的應(yīng)用場(chǎng)景密切相關(guān)的。

同樣的,我們就結(jié)合現(xiàn)實(shí)場(chǎng)景,來回答這三個(gè)問題

(1) JS為什么是單線程的?

JS最初被設(shè)計(jì)用在瀏覽器中,那么想象一下,如果瀏覽器中的JS是多線程的。

場(chǎng)景描述:

那么現(xiàn)在有2個(gè)線程,process1 process2,由于是多線程的JS,所以他們對(duì)同一個(gè)dom,同時(shí)進(jìn)行操作

process1 刪除了該dom,而process2 編輯了該dom,同時(shí)下達(dá)2個(gè)矛盾的命令,瀏覽器究竟該如何執(zhí)行呢?

這樣想,JS為什么被設(shè)計(jì)成單線程應(yīng)該就容易理解了吧。

(2) JS為什么需要異步?
場(chǎng)景描述:

如果JS中不存在異步,只能自上而下執(zhí)行,如果上一行解析時(shí)間很長(zhǎng),那么下面的代碼就會(huì)被阻塞。
對(duì)于用戶而言,阻塞就意味著"卡死",這樣就導(dǎo)致了很差的用戶體驗(yàn)

所以,JS中存在異步執(zhí)行。

(3) JS單線程又是如何實(shí)現(xiàn)異步的呢?

既然JS是單線程的,只能在一條線程上執(zhí)行,又是如何實(shí)現(xiàn)的異步呢?

是通過的事件循環(huán)(event loop),理解了event loop機(jī)制,就理解了JS的執(zhí)行機(jī)制

2.JS中的event loop(1)

例1,觀察它的執(zhí)行順序

    console.log(1)
    
    setTimeout(function(){
        console.log(2)
    },0)

    console.log(3)
    

運(yùn)行結(jié)果是: 1 3 2

也就是說,setTimeout里的函數(shù)并沒有立即執(zhí)行,而是延遲了一段時(shí)間,滿足一定條件后,才去執(zhí)行的,這類代碼,我們叫異步代碼。

所以,這里我們首先知道了JS里的一種分類方式,就是將任務(wù)分為: 同步任務(wù)和異步任務(wù)

圖片描述

按照這種分類方式:JS的執(zhí)行機(jī)制是

首先判斷JS是同步還是異步,同步就進(jìn)入主線程,異步就進(jìn)入event table

異步任務(wù)在event table中注冊(cè)函數(shù),當(dāng)滿足觸發(fā)條件后,被推入event queue

同步任務(wù)進(jìn)入主線程后一直執(zhí)行,直到主線程空閑時(shí),才會(huì)去event queue中查看是否有可執(zhí)行的異步任務(wù),如果有就推入主線程中

以上三步循環(huán)執(zhí)行,這就是event loop

所以上面的例子,你是否可以描述它的執(zhí)行順序了呢?

console.log(1) 是同步任務(wù),放入主線程里
setTimeout() 是異步任務(wù),被放入event table, 0秒之后被推入event queue里
console.log(3 是同步任務(wù),放到主線程里

當(dāng) 1、 3在控制條被打印后,主線程去event queue(事件隊(duì)列)里查看是否有可執(zhí)行的函數(shù),執(zhí)行setTimeout里的函數(shù)
3.JS中的event loop(2)

所以,上面關(guān)于event loop就是我對(duì)JS執(zhí)行機(jī)制的理解,直到我遇到了下面這段代碼

例2:

 setTimeout(function(){
     console.log("定時(shí)器開始啦")
 });
 
 new Promise(function(resolve){
     console.log("馬上執(zhí)行for循環(huán)啦");
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log("執(zhí)行then函數(shù)啦")
 });
 
 console.log("代碼執(zhí)行結(jié)束");
    

嘗試按照,上文我們剛學(xué)到的JS執(zhí)行機(jī)制去分析

setTimeout 是異步任務(wù),被放到event table

new Promise 是同步任務(wù),被放到主線程里,直接執(zhí)行打印 console.log("馬上執(zhí)行for循環(huán)啦")

.then里的函數(shù)是 異步任務(wù),被放到event table

 console.log("代碼執(zhí)行結(jié)束")是同步代碼,被放到主線程里,直接執(zhí)行
 

所以,結(jié)果是 【馬上執(zhí)行for循環(huán)啦 --- 代碼執(zhí)行結(jié)束 --- 定時(shí)器開始啦 --- 執(zhí)行then函數(shù)啦】嗎?

親自執(zhí)行后,結(jié)果居然不是這樣,而是【馬上執(zhí)行for循環(huán)啦 --- 代碼執(zhí)行結(jié)束 --- 執(zhí)行then函數(shù)啦 --- 定時(shí)器開始啦】

那么,難道是異步任務(wù)的執(zhí)行順序,不是前后順序,而是另有規(guī)定? 事實(shí)上,按照異步和同步的劃分方式,并不準(zhǔn)確。

而準(zhǔn)確的劃分方式是:

macro-task(宏任務(wù)):包括整體代碼script,setTimeout,setInterval

micro-task(微任務(wù)):Promise,process.nextTick

按照這種分類方式:JS的執(zhí)行機(jī)制是

執(zhí)行一個(gè)宏任務(wù),過程中如果遇到微任務(wù),就將其放到微任務(wù)的【事件隊(duì)列】里

當(dāng)前宏任務(wù)執(zhí)行完成后,會(huì)查看微任務(wù)的【事件隊(duì)列】,并將里面全部的微任務(wù)依次執(zhí)行完

重復(fù)以上2步驟,結(jié)合event loop(1) event loop(2) ,就是更為準(zhǔn)確的JS執(zhí)行機(jī)制了。

嘗試按照剛學(xué)的執(zhí)行機(jī)制,去分析例2:

首先執(zhí)行script下的宏任務(wù),遇到setTimeout,將其放到宏任務(wù)的【隊(duì)列】里

遇到 new Promise直接執(zhí)行,打印"馬上執(zhí)行for循環(huán)啦"

遇到then方法,是微任務(wù),將其放到微任務(wù)的【隊(duì)列里】

打印 "代碼執(zhí)行結(jié)束"

本輪宏任務(wù)執(zhí)行完畢,查看本輪的微任務(wù),發(fā)現(xiàn)有一個(gè)then方法里的函數(shù), 打印"執(zhí)行then函數(shù)啦"

到此,本輪的event loop 全部完成。


下一輪的循環(huán)里,先執(zhí)行一個(gè)宏任務(wù),發(fā)現(xiàn)宏任務(wù)的【隊(duì)列】里有一個(gè) setTimeout里的函數(shù),執(zhí)行打印"定時(shí)器開始啦"

所以最后的執(zhí)行順序是【馬上執(zhí)行for循環(huán)啦 --- 代碼執(zhí)行結(jié)束 --- 執(zhí)行then函數(shù)啦 --- 定時(shí)器開始啦】

4. 談?wù)剆etTimeout

這段setTimeout代碼什么意思? 我們一般說: 3秒后,會(huì)執(zhí)行setTimeout里的那個(gè)函數(shù)

 setTimeout(function(){
    console.log("執(zhí)行了")
 },3000)    

但是這種說并不嚴(yán)謹(jǐn),準(zhǔn)確的解釋是: 3秒后,setTimeout里的函數(shù)被會(huì)推入event queue,而event queue(事件隊(duì)列)里的任務(wù),只有在主線程空閑時(shí)才會(huì)執(zhí)行。

所以只有滿足 (1)3秒后 (2)主線程空閑,同時(shí)滿足時(shí),才會(huì)3秒后執(zhí)行該函數(shù)

如果主線程執(zhí)行內(nèi)容很多,執(zhí)行時(shí)間超過3秒,比如執(zhí)行了10秒,那么這個(gè)函數(shù)只能10秒后執(zhí)行了

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/110103.html

相關(guān)文章

  • JavaScript 事件機(jī)制

    摘要:的事件機(jī)制關(guān)于,查閱多篇博客,或多或少總有些出入,在此寫下自己關(guān)于的理解按同步與異步分首先判斷是同步還是異步同步就進(jìn)入主進(jìn)程異步就進(jìn)入異步任務(wù)在中注冊(cè)函數(shù)當(dāng)滿足觸發(fā)條件后被推入同步任務(wù)進(jìn)入主線程后一直執(zhí)行直到主線程空閑時(shí)才會(huì)去中查看是否有可 JavaScript 的事件機(jī)制 關(guān)于Event Loop,查閱多篇博客,或多或少總有些出入,在此寫下自己關(guān)于Event Loop的理解 按同步與...

    Turbo 評(píng)論0 收藏0
  • JS 異步實(shí)現(xiàn)

    摘要:由于引擎同一時(shí)間只執(zhí)行一段代碼這是由單線程的性質(zhì)決定的,所以每個(gè)代碼塊阻塞了其它異步事件的進(jìn)行。這意味著瀏覽器將等待著一個(gè)新的異步事件發(fā)生。異步的任務(wù)執(zhí)行的順序是不固定的,主要看返回的速度。 我們經(jīng)常說JS是單線程的,比如node.js研討會(huì)上大家都說JS的特色之一是單線程的,這樣使JS更簡(jiǎn)單明了,可是大家真的理解所謂JS的單線程機(jī)制嗎?單線程時(shí),基于事件的異步機(jī)制又該當(dāng)如何,這些知識(shí)...

    sihai 評(píng)論0 收藏0
  • 從底層看JS執(zhí)行機(jī)制

    摘要:作用域鏈用于表明上下文的執(zhí)行順序。當(dāng)前上下文執(zhí)行完畢則出棧,執(zhí)行下一個(gè)上下文。 從一個(gè)簡(jiǎn)單的例子出發(fā) 先從一個(gè)簡(jiǎn)單的例子出發(fā)(先不涉及異步),看看自己是否大致了解瀏覽器的執(zhí)行機(jī)制: console.log(a); var a=1; function foo(a){ console.log(a); var a=2; console.log(a); } foo(a)...

    thursday 評(píng)論0 收藏0
  • JS核心知識(shí)點(diǎn)梳理——異步,單線程,運(yùn)行機(jī)制

    摘要:引言學(xué)習(xí)的時(shí)候,經(jīng)常聽人說,即是異步的,又是單線程的。所以我們說是異步單線程的。參考從瀏覽器多進(jìn)程到單線程,運(yùn)行機(jī)制最全面的一次梳理運(yùn)行機(jī)制詳解再談異步機(jī)制詳解運(yùn)行原理解析并發(fā)模型與事件循環(huán) showImg(https://segmentfault.com/img/bVbo4hv?w=1800&h=1000); 引言 學(xué)習(xí)javascipt的時(shí)候,經(jīng)常聽人說,javascipt即是異步...

    TANKING 評(píng)論0 收藏0
  • Event Loop - JS執(zhí)行機(jī)制

    摘要:心塞塞根據(jù)規(guī)范,事件循環(huán)是通過任務(wù)隊(duì)列的機(jī)制來進(jìn)行協(xié)調(diào)的。等便是任務(wù)源,而進(jìn)入任務(wù)隊(duì)列的是他們指定的具體執(zhí)行任務(wù)回調(diào)函數(shù)。然后當(dāng)前本輪的結(jié)束,主線程可以繼續(xù)取下一個(gè)執(zhí)行。 依然是:經(jīng)濟(jì)基礎(chǔ)決定上層建筑。 說明 首先,旨在搞清常用的同步異步執(zhí)行機(jī)制 其次,暫時(shí)不討論node.js的Event Loop執(zhí)行機(jī)制,以下關(guān)于瀏覽器的Event Loop執(zhí)行機(jī)制 最后,借鑒了很多前輩的研究文...

    muddyway 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<