欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2022年07月28日 14:10:42   作者:尼克_張  
這篇文章主要介紹了JavaScript中的事件循環(huán)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

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

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

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

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

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

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

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

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

概述原理

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

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

2.進行第一輪事件循環(huán)的時候會把js腳本當成一個宏任務(wù)來運行。

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

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

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

案例解析

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

解析

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

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

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

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

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

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

將以上代碼升級下:

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ù)中?

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

解析

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

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

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

4.遇到console.log(‘5’),立即執(zhí)行。

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

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

最后的執(zhí)行順序為2 5 3 4 1

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論