成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

JavaScript同步、異步及事件循環(huán)

zr_hebo / 1764人閱讀

摘要:同步異步是單線程的,每次只能做一件事情。像以下這種情況,代碼會按順序執(zhí)行,這個就叫同步。雖然是單線程,但是瀏覽器是多線程的,在遇到像事件等這種任務(wù)時,會轉(zhuǎn)交給瀏覽器的其他工作線程上面提到的幾個線程執(zhí)行,執(zhí)行完之后將回調(diào)函數(shù)放入到任務(wù)隊列。

同步、異步

JS是單線程的,每次只能做一件事情。像以下這種情況,代碼會按順序執(zhí)行,這個就叫同步。

console.log(1);
console.log(2);
console.log(3);

以下代碼會輸出2、3、1,像這種不按順序執(zhí)行的,或者說代碼執(zhí)行中間有時間間隙的,叫異步。

setTimeout(() => {
    console.log(1);
}, 0);
console.log(2);
console.log(3);
事件循環(huán)

一個瀏覽器通常有以下幾個常駐的線程:

渲染引擎線程:該線程負(fù)責(zé)頁面的渲染

JS引擎線程:負(fù)責(zé)JS的解析和執(zhí)行

定時觸發(fā)器線程:處理定時事件,比如setTimeout, setInterval

事件觸發(fā)線程:處理DOM事件

異步http請求線程:處理http請求

渲染線程和JS引擎線程是不能同時進(jìn)行的。也就是說在執(zhí)行代碼時,渲染會掛起;渲染DOM時,代碼也不會執(zhí)行。
雖然JS是單線程,但是瀏覽器是多線程的,在遇到像setTimeout、DOM事件、ajax等這種任務(wù)時,會轉(zhuǎn)交給瀏覽器的其他工作線程(上面提到的幾個線程)執(zhí)行,執(zhí)行完之后將回調(diào)函數(shù)放入到任務(wù)隊列。

在JS運(yùn)行環(huán)境里,除了主線程外,還有任務(wù)隊列。

// eventLoop是一個用作隊列的數(shù)組
// (先進(jìn),先出)
var eventLoop = [ ];
var event;
// “永遠(yuǎn)”執(zhí)行
while (true) {
    // 一次tick
    if (eventLoop.length > 0) {
        // 拿到隊列中的下一個事件
        event = eventLoop.shift();
        // 現(xiàn)在,執(zhí)行下一個事件
        event();
    }
}

我們可以用上面的代碼來想像一下JS的執(zhí)行情況。

JS主線程,就像是一個while循環(huán),會一直執(zhí)行下去。在這期間,每次都會查看任務(wù)隊列有沒有需要執(zhí)行的任務(wù)(回調(diào)函數(shù))。在執(zhí)行完一個任務(wù)之后,會繼續(xù)下一個循環(huán),直到任務(wù)隊列所有任務(wù)都執(zhí)行完為止。

microtask(微任務(wù))、macrotask(宏任務(wù))

任務(wù)隊列又分微任務(wù)隊列和宏任務(wù)隊列

微任務(wù)

Promise

MutationObserver

Object.observe()(已廢棄)

宏任務(wù)

setTimeout

setInterval

setImmediate

IO

UI rendering(DOM event)

執(zhí)行過程

在JS執(zhí)行完同步任務(wù)之后,會開始執(zhí)行微任務(wù)隊列

在將所有的微任務(wù)執(zhí)行完之后,會開始執(zhí)行宏任務(wù)隊列

在執(zhí)行完一個宏任務(wù)之后,跳出來,重新開始下一個循環(huán)(從1開始執(zhí)行)

也就是說執(zhí)行微任務(wù)隊列 會將隊列中的所有微任務(wù)執(zhí)行完 而執(zhí)行宏任務(wù)隊列 每次只執(zhí)行一個宏任務(wù) 然后重新開始下一個循環(huán)
我們可以看看以下代碼

setTimeout(() => {
    console.log(3)
    new Promise((resolve, reject) => {
        console.log(5)
        resolve()
    }).then(console.log(6))
}, 0)

setTimeout(() => {
    console.log(4)
}, 0)

new Promise((resolve, reject) => {
    console.log(1)
    resolve()
}).then(console.log(2))

輸出是1 2 3 5 6 4

我們來分析一下代碼的執(zhí)行過程

前面的兩個setTimeout都是宏任務(wù),所以現(xiàn)在宏任務(wù)隊列有2個任務(wù)

Promise里面的代碼是同步任務(wù),所以現(xiàn)在會馬上執(zhí)行 輸出1

Promise的then是微任務(wù),所以現(xiàn)在微任務(wù)隊列有1個任務(wù)

在執(zhí)行完同步任務(wù)之后,開始執(zhí)行微任務(wù),也就是console.log(2), 輸出2

在執(zhí)行完微任務(wù)之后,會執(zhí)行宏任務(wù),第一個宏任務(wù)也就是第一個setTimeout

第一個setTimeout會先輸出3,然后輸出5,因?yàn)檫@兩個都是同步任務(wù),然后遇到then,加入微任務(wù)隊列,宏任務(wù)執(zhí)行完重新開始下一個循環(huán)。

因?yàn)闆]有同步代碼,所以接著執(zhí)行微任務(wù),此時微任務(wù)隊列有1個任務(wù)(第6步加入), 宏任務(wù)隊列還有1個任務(wù)(第6步執(zhí)行完了第一個宏任務(wù))

執(zhí)行微任務(wù),輸出6

再執(zhí)行宏任務(wù),輸出4

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

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

相關(guān)文章

  • 淺析JavaScript異步

    摘要:回調(diào)函數(shù),一般在同步情境下是最后執(zhí)行的,而在異步情境下有可能不執(zhí)行,因?yàn)槭录]有被觸發(fā)或者條件不滿足。同步方式請求異步同步請求當(dāng)請求開始發(fā)送時,瀏覽器事件線程通知主線程,讓線程發(fā)送數(shù)據(jù)請求,主線程收到 一直以來都知道JavaScript是一門單線程語言,在筆試過程中不斷的遇到一些輸出結(jié)果的問題,考量的是對異步編程掌握情況。一般被問到異步的時候腦子里第一反應(yīng)就是Ajax,setTimse...

    Tangpj 評論0 收藏0
  • JavaScript 工作原理之四-事件循環(huán)異步編程的出現(xiàn)和 5 種更好的 async/await

    摘要:函數(shù)會在之后的某個時刻觸發(fā)事件定時器。事件循環(huán)中的這樣一次遍歷被稱為一個。執(zhí)行完畢并出棧。當(dāng)定時器過期,宿主環(huán)境會把回調(diào)函數(shù)添加至事件循環(huán)隊列中,然后,在未來的某個取出并執(zhí)行該事件。 原文請查閱這里,略有改動。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現(xiàn)在,我們將會通過回顧單線程環(huán)境下編程的弊端及如何克服這些困難以創(chuàng)建令人驚嘆...

    maochunguang 評論0 收藏0
  • (轉(zhuǎn))JavaScript同步異步事件循環(huán)

    摘要:事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊列中取消息執(zhí)行的過程。事件觸發(fā)時,表示異步任務(wù)完成,會將事件監(jiān)聽器函數(shù)封裝成一條消息放到消息隊列中,等待主線程執(zhí)行。 一. 單線程 我們常說JavaScript是單線程的。 所謂單線程,是指在JS引擎中負(fù)責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個。不妨叫它主線程。 但是實(shí)際上還存在其他的線程。例如:處理AJAX請求的線程、處理DOM事件的線...

    android_c 評論0 收藏0
  • js的單線程,異步回調(diào)函數(shù)

    摘要:當(dāng)主線程開始執(zhí)行異步任務(wù),實(shí)際就是執(zhí)行對應(yīng)的回調(diào)函數(shù)。異步任務(wù)必須指定回調(diào)函數(shù)。所以注意的是,只是將事件插入了任務(wù)隊列,必須等到當(dāng)前代碼執(zhí)行棧執(zhí)行完,主線程才會去執(zhí)行它指定的回調(diào)函數(shù)。 最近本人對于js的運(yùn)行機(jī)制,特別是異步,還有回調(diào)函數(shù)感覺很亂,于是參考了很多有用的博客(博客原文地址會在文末給出),整理如下: js單線程 我們都知道,Javascript語言的執(zhí)行環(huán)境是單線程(si...

    Songlcy 評論0 收藏0

發(fā)表評論

0條評論

zr_hebo

|高級講師

TA的文章

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