溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中的事件循環(huán)方式是什么

發(fā)布時(shí)間:2022-07-28 16:13:45 來(lái)源:億速云 閱讀:107 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“JavaScript中的事件循環(huán)方式是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

js是單線程,非阻塞,試想如果是多線程,一個(gè)線程在某個(gè)DOM節(jié)點(diǎn)上添加內(nèi)容,另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn),這時(shí)瀏覽器應(yīng)該以哪個(gè)線程為準(zhǔn)?所以,為了避免復(fù)雜性,從一誕生,JavaScript就是單線程。

js的事件循環(huán)分為主線程(同步)和任務(wù)隊(duì)列(異步),任務(wù)隊(duì)列里又分為宏任務(wù)和微任務(wù)

JavaScript中的事件循環(huán)方式是什么

1.宏任務(wù)(macro-task):

script(整體代碼),setTimeout,setInterval,setImmediate。

優(yōu)先級(jí): setImmediate > setTimeout / setInterval 

2.微任務(wù)(micro-task):

Promise,mutationObserve(觀察DOM樹(shù)結(jié)構(gòu)發(fā)生變化時(shí),做出相應(yīng)處理),process.nextTick(Node.js 環(huán)境)。

優(yōu)先級(jí):process.nextTick > Promise > MutationObserver

概述原理

同步>微任務(wù)>宏任務(wù)

1.宏任務(wù)、微任務(wù)都是任務(wù)隊(duì)列,一段代碼執(zhí)行時(shí),會(huì)先執(zhí)行宏任務(wù)中的同步代碼。

2.進(jìn)行第一輪事件循環(huán)的時(shí)候會(huì)把js腳本當(dāng)成一個(gè)宏任務(wù)來(lái)運(yùn)行。

3.如果執(zhí)行中遇到setTimeout之類(lèi)宏任務(wù),那么就把這個(gè)setTimeout內(nèi)部的函數(shù)推入宏任務(wù)的隊(duì)列中,下一輪宏任務(wù)執(zhí)行時(shí)調(diào)用。

4.如果執(zhí)行中遇到 promise.then() 之類(lèi)的微任務(wù),就會(huì)推入到微任務(wù)隊(duì)列中,在本輪宏任務(wù)的同步代碼都執(zhí)行完成后,依次執(zhí)行所有的微任務(wù)。

5.當(dāng)執(zhí)行完全部的同步腳本以及微任務(wù)隊(duì)列中的事件,這一輪循環(huán)就結(jié)束了,開(kāi)始第二輪循環(huán),依次循環(huán)往復(fù)。

JavaScript中的事件循環(huán)方式是什么

案例解析

<script>
setTimeout(() => {
    console.log('4')
}, 100)
new Promise((resolve) => {
    console.log('1')
    resolve("成功")
}).then(data => {
    console.log(data)
})
console.log('2')
</script>

解析

1.這段代碼作為宏任務(wù),進(jìn)入主線程。

2.先遇到setTimeout之類(lèi)宏任務(wù),那么就把這個(gè)setTimeout內(nèi)部的函數(shù)推入宏任務(wù)的隊(duì)列中,下一輪宏任務(wù)執(zhí)行時(shí)調(diào)用。

3.接下來(lái)遇到了Promise,同步代碼立即執(zhí)行,回調(diào)函數(shù)分發(fā)到微任務(wù)隊(duì)列中。

4.遇到console.log(&lsquo;2&rsquo;),立即執(zhí)行,查看有無(wú)微任務(wù),有一個(gè)then的回調(diào)函數(shù),立即執(zhí)行。

5.第一輪宏任務(wù)執(zhí)行結(jié)束。

6.開(kāi)始第二輪宏任務(wù),執(zhí)行宏任務(wù)中的setTimeout函數(shù)。

將以上代碼升級(jí)下:

setTimeout(() => {
    console.log('1') 
}, 1000)
new Promise((resolve) => {
    console.log('2') 
    setTimeout((params) => {
        resolve("4")
        console.log("3"); 
    }, 100)
}).then(data => {
    console.log(data) 
})
console.log('5')

能否先將promise.then分發(fā)到微任務(wù)中?

答案是不能,因?yàn)橹挥衦esolve成功回調(diào)之后才能執(zhí)行.then,而現(xiàn)在resolve在setTimeout宏任務(wù)中,只有等setTimeout執(zhí)行完之后才能執(zhí)行.then中的微任務(wù) 

解析

1.這段代碼作為宏任務(wù),進(jìn)入主線程。

2.先遇到等待時(shí)間為1000ms的setTimeout,記為s1,并且把這個(gè)setTimeout內(nèi)部的函數(shù)推入宏任務(wù)的隊(duì)列中,下一輪宏任務(wù)執(zhí)行時(shí)調(diào)用。

3.接下來(lái)遇到了Promise,同步代碼立即執(zhí)行,但其內(nèi)部包含一個(gè)等待時(shí)間為100ms的setTimeout,記為s2,并且promise的resolve也在其中,也把它放在下一輪的宏任務(wù)中。

4.遇到console.log(&lsquo;5&rsquo;),立即執(zhí)行。

5.第一輪宏任務(wù)執(zhí)行結(jié)束。查看當(dāng)前有沒(méi)有可執(zhí)行的微任務(wù),沒(méi)有則執(zhí)行宏任務(wù)。

6.開(kāi)啟第二輪宏任務(wù),發(fā)現(xiàn)有兩個(gè)宏任務(wù),比較等待時(shí)間長(zhǎng)短,時(shí)間短的先執(zhí)行,先執(zhí)行s2,發(fā)現(xiàn)其中有微任務(wù)promise.then,立即執(zhí)行,再執(zhí)行s1。

最后的執(zhí)行順序?yàn)? 5 3 4 1

“JavaScript中的事件循環(huán)方式是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI