成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

JavaScript運(yùn)行機(jī)制的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)JavaScript運(yùn)行機(jī)制的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

十余年的大埔網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整大埔建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“大埔網(wǎng)站設(shè)計(jì)”,“大埔網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

說javascript運(yùn)行機(jī)制之前,先看一段代碼:

console.log(1)
Promise.resolve().then(function () {
   console.log(2)
})
new Promise(function(resolve, reject){
    console.log(3)
    resolve()
}).then(function () {
    console.log(4)
    setTimeout(function () {
        console.log(5)
    })
})
console.log(6)
setTimeout(function () {
    Promise.resolve().then(function () {
        console.log(7)
        setTimeout(function () {
            console.log(8)
        })
    })
})

如果你看到這段代碼,并知道正確的輸出順序。那說明你對這塊掌握的差不多了。(直接翻到最后看結(jié)果)

好,言歸正傳。

在說是怎么運(yùn)行的之前,先看幾個(gè)概念。

執(zhí)行上下文(Execution Context)

執(zhí)行上下文簡單來說就是一個(gè)執(zhí)行環(huán)境。它有全局環(huán)境、函數(shù)環(huán)境和eval函數(shù)環(huán)境之分。它會在javascript引擎執(zhí)行你的腳本的時(shí)候去創(chuàng)建。

執(zhí)行棧(Execution Stack)

執(zhí)行棧也就是常說的調(diào)用棧,它是一種擁有LIFO(后進(jìn)先出)的數(shù)據(jù)結(jié)構(gòu)。它會存儲代碼運(yùn)行時(shí)創(chuàng)建的執(zhí)行上下文

微任務(wù)(micro task)與宏任務(wù)(macro task)

javasript中的任務(wù)分為微任務(wù)和宏任務(wù)兩種,這兩種任務(wù)的執(zhí)行時(shí)機(jī)是不同的,因此區(qū)分js中哪些是宏任務(wù),哪些是微任務(wù)則十分重要。我們常見的宏任務(wù)有:script任務(wù)、setTimeout、ajax等,常見的微任務(wù)比較典型的是:Promise.resolve().then()、process.nextTick、MutationObserver等。

事件循環(huán)(event loop)

js是單線程的,也就是說它一次僅能處理一個(gè)任務(wù)。但js所在的宿主環(huán)境,也就是我們所說的瀏覽器并不是單線程的(這里宿主環(huán)境僅討論瀏覽器)。它在遇到一些任務(wù)時(shí),比如說setTimeout、event listener等。它會告訴瀏覽器:老兄幫個(gè)忙,事成后通知我一聲,小弟我先干別的事去了。瀏覽器會回應(yīng)說:交給我吧,小老弟,事成后我放到任務(wù)隊(duì)列,自己去取啊。于是,js開始執(zhí)行script任務(wù),執(zhí)行完了就開始檢查有沒有微任務(wù)啊,沒有的話就從任務(wù)隊(duì)列開始取宏任務(wù)執(zhí)行,每執(zhí)行完一次宏任務(wù),就去看看有沒有微任務(wù),有的話就執(zhí)行完成,再執(zhí)行宏任務(wù),如此往復(fù)。如下:

JavaScript運(yùn)行機(jī)制的示例分析

了解了這幾個(gè)概念,再來看看javascript是怎么執(zhí)行代碼的就比較輕松愉快了。開始吧

console.log(1)

Promise.resolve().then(function () {
   console.log(2)
})

new Promise(function(resolve, reject){
    console.log(3)
    resolve()
}).then(function () {
    console.log(4)
    setTimeout(function () {
        console.log(5)
    })
})

console.log(6)

setTimeout(function () {
    Promise.resolve().then(function () {
        console.log(7)
        setTimeout(function () {
            console.log(8)
        })
    })
})

js引擎在執(zhí)行這段代碼的時(shí)候,首先將全局執(zhí)行上下文壓入棧中:

JavaScript運(yùn)行機(jī)制的示例分析

然后呢,在執(zhí)行的時(shí)候會碰到console.log函數(shù),將它壓入棧中:

JavaScript運(yùn)行機(jī)制的示例分析

這個(gè)時(shí)候,直接執(zhí)行console函數(shù),并輸出1。然后console函數(shù)出棧:

JavaScript運(yùn)行機(jī)制的示例分析

繼續(xù)往下執(zhí)行,碰到了Promise.resolve().then(),先將Promise.resolve().then()壓入棧中(這里,我為了圖方便就把它看成整體了,不然得畫很多圖)。

JavaScript運(yùn)行機(jī)制的示例分析

然后執(zhí)行Promise.resolve().then(),前面說過,這個(gè)then()函數(shù)是個(gè)微任務(wù),它會將傳入給它的回調(diào)函數(shù)加入到微任務(wù)隊(duì)列中。

JavaScript運(yùn)行機(jī)制的示例分析

然后Promise.resolve().then()就出棧了。

接著執(zhí)行,遇到promise的構(gòu)造函數(shù),這個(gè)構(gòu)造函數(shù)是一個(gè)宏任務(wù),會直接將傳遞給它的函數(shù)壓入棧中。

JavaScript運(yùn)行機(jī)制的示例分析
執(zhí)行console函數(shù)并輸出3,執(zhí)行完,console函數(shù)出棧,接著執(zhí)行resolve()函數(shù),并出棧。
然后繼續(xù)執(zhí)行then函數(shù),將傳遞給then函數(shù)的參數(shù)函數(shù)放到微任務(wù)隊(duì)列中:

JavaScript運(yùn)行機(jī)制的示例分析

繼續(xù)來,繼續(xù)往下執(zhí)行。碰到console.log(6),二話不說,直接壓入棧中,執(zhí)行,輸出6,出棧,一氣呵成。

接著,引擎碰到了setTimeout函數(shù),這家伙是個(gè)宏任務(wù),但同時(shí)它會將傳遞給它的函數(shù),加入到任務(wù)隊(duì)列中:

JavaScript運(yùn)行機(jī)制的示例分析

好了,到此第一波宏任務(wù)就全部執(zhí)行完畢。接著,引擎就會去看一下微任務(wù)隊(duì)列中有沒有任務(wù),如果有的話,執(zhí)行它們。

現(xiàn)在看到的是,微任務(wù)隊(duì)列中有兩個(gè)任務(wù)。按照隊(duì)列的先入先出規(guī)則,先從function () {console.log(2)}開始執(zhí)行。先是函數(shù)入棧,然后執(zhí)行函數(shù),輸出2,然后函數(shù)出棧。

接著執(zhí)行下面這段代碼:

console.log(4)
setTimeout(function () {
   console.log(5)
})

先從console.log(4)開始,先將它入棧,然后執(zhí)行它,輸出4,然后函數(shù)出棧。

接著執(zhí)行:

setTimeout(function () {
   console.log(5)
})

function () {
    console.log(5)
}

加入到任務(wù)隊(duì)列中去

JavaScript運(yùn)行機(jī)制的示例分析

先執(zhí)行:

function(){
Promise.resolve().then(function () {
        console.log(7)
        setTimeout(function () {
            console.log(8)
        })
    })
}

這里執(zhí)行這個(gè)函數(shù)的時(shí)候遇到一個(gè)微任務(wù),將這個(gè)微任務(wù)添加到微任務(wù)隊(duì)列,如下:

JavaScript運(yùn)行機(jī)制的示例分析

這批次的宏任務(wù)就執(zhí)行完畢了,接著就回去檢查微任務(wù)隊(duì)列中有沒有待執(zhí)行的任務(wù)。一看還真有兩個(gè)小可愛等待執(zhí)行,于是沒什么好說的,直接擰出去就執(zhí)行

先是執(zhí)行console.log(7),然后輸出7。接著執(zhí)行setTimeout,將傳遞給他的任務(wù)添加到任務(wù)隊(duì)列中去:

JavaScript運(yùn)行機(jī)制的示例分析

最后就剩這兩個(gè)函數(shù)了,按照隊(duì)列的先入后出一次執(zhí)行吧,輸出5和8。

好了,最后的結(jié)果就是1,3,6,2,4,7,5,8。你寫對了了嗎?

關(guān)于JavaScript運(yùn)行機(jī)制的示例分析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

當(dāng)前文章:JavaScript運(yùn)行機(jī)制的示例分析
標(biāo)題鏈接:http://jinyejixie.com/article8/pgehop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、軟件開發(fā)企業(yè)建站、營銷型網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化

廣告

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

綿陽服務(wù)器托管
乌兰察布市| 满城县| 濮阳县| 工布江达县| 桂阳县| 右玉县| 聊城市| 建水县| 阿图什市| 海南省| 香港 | 咸丰县| 宁远县| 天门市| 新野县| 淮阳县| 姜堰市| 峨山| 乐安县| 庆云县| 大丰市| 乳源| 当涂县| 紫阳县| 肥东县| 榆林市| 莱阳市| 外汇| 陈巴尔虎旗| 鸡东县| 祁门县| 上林县| 栾城县| 五大连池市| 涟源市| 荣昌县| 平果县| 大关县| 苍溪县| 湖口县| 肥乡县|