中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript運行機制的示例分析

發布時間:2020-12-05 11:06:18 來源:億速云 閱讀:151 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關JavaScript運行機制的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

說javascript運行機制之前,先看一段代碼:

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)
        })
    })
})

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

好,言歸正傳。

在說是怎么運行的之前,先看幾個概念。

執行上下文(Execution Context)

執行上下文簡單來說就是一個執行環境。它有全局環境、函數環境和eval函數環境之分。它會在javascript引擎執行你的腳本的時候去創建。

執行棧(Execution Stack)

執行棧也就是常說的調用棧,它是一種擁有LIFO(后進先出)的數據結構。它會存儲代碼運行時創建的執行上下文

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

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

事件循環(event loop)

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

JavaScript運行機制的示例分析

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

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引擎在執行這段代碼的時候,首先將全局執行上下文壓入棧中:

JavaScript運行機制的示例分析

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

JavaScript運行機制的示例分析

這個時候,直接執行console函數,并輸出1。然后console函數出棧:

JavaScript運行機制的示例分析

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

JavaScript運行機制的示例分析

然后執行Promise.resolve().then(),前面說過,這個then()函數是個微任務,它會將傳入給它的回調函數加入到微任務隊列中。

JavaScript運行機制的示例分析

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

接著執行,遇到promise的構造函數,這個構造函數是一個宏任務,會直接將傳遞給它的函數壓入棧中。

JavaScript運行機制的示例分析
執行console函數并輸出3,執行完,console函數出棧,接著執行resolve()函數,并出棧。
然后繼續執行then函數,將傳遞給then函數的參數函數放到微任務隊列中:

JavaScript運行機制的示例分析

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

接著,引擎碰到了setTimeout函數,這家伙是個宏任務,但同時它會將傳遞給它的函數,加入到任務隊列中:

JavaScript運行機制的示例分析

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

現在看到的是,微任務隊列中有兩個任務。按照隊列的先入先出規則,先從function () {console.log(2)}開始執行。先是函數入棧,然后執行函數,輸出2,然后函數出棧。

接著執行下面這段代碼:

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

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

接著執行:

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

function () {
    console.log(5)
}

加入到任務隊列中去

JavaScript運行機制的示例分析

先執行:

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

這里執行這個函數的時候遇到一個微任務,將這個微任務添加到微任務隊列,如下:

JavaScript運行機制的示例分析

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

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

JavaScript運行機制的示例分析

最后就剩這兩個函數了,按照隊列的先入后出一次執行吧,輸出5和8。

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

關于JavaScript運行機制的示例分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

怀来县| 册亨县| 阳城县| 土默特右旗| 塔城市| 临安市| 德令哈市| 龙泉市| 航空| 抚远县| 利川市| 博客| 静海县| 苍南县| 华容县| 石渠县| 西安市| 长宁县| 阳春市| 荔浦县| 延津县| 山阴县| 广元市| 宁都县| 中阳县| 什邡市| 柳河县| 渝北区| 大庆市| 石楼县| 吴川市| 杭锦旗| 阳谷县| 丹棱县| 阿拉善左旗| 南部县| 盐源县| 健康| 阿荣旗| 台安县| 永康市|