您好,登錄后才能下訂單哦!
本篇內容介紹了“JavaScript中的事件循環方式是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
js是單線程,非阻塞,試想如果是多線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準?所以,為了避免復雜性,從一誕生,JavaScript就是單線程。
js的事件循環分為主線程(同步)和任務隊列(異步),任務隊列里又分為宏任務和微任務
1.宏任務(macro-task):
script(整體代碼),setTimeout,setInterval,setImmediate。
優先級: setImmediate > setTimeout / setInterval
2.微任務(micro-task):
Promise,mutationObserve(觀察DOM樹結構發生變化時,做出相應處理),process.nextTick(Node.js 環境)。
優先級:process.nextTick > Promise > MutationObserver
1.宏任務、微任務都是任務隊列,一段代碼執行時,會先執行宏任務中的同步代碼。
2.進行第一輪事件循環的時候會把js腳本當成一個宏任務來運行。
3.如果執行中遇到setTimeout之類宏任務,那么就把這個setTimeout內部的函數推入宏任務的隊列中,下一輪宏任務執行時調用。
4.如果執行中遇到 promise.then() 之類的微任務,就會推入到微任務隊列中,在本輪宏任務的同步代碼都執行完成后,依次執行所有的微任務。
5.當執行完全部的同步腳本以及微任務隊列中的事件,這一輪循環就結束了,開始第二輪循環,依次循環往復。
<script> setTimeout(() => { console.log('4') }, 100) new Promise((resolve) => { console.log('1') resolve("成功") }).then(data => { console.log(data) }) console.log('2') </script>
解析
1.這段代碼作為宏任務,進入主線程。
2.先遇到setTimeout之類宏任務,那么就把這個setTimeout內部的函數推入宏任務的隊列中,下一輪宏任務執行時調用。
3.接下來遇到了Promise,同步代碼立即執行,回調函數分發到微任務隊列中。
4.遇到console.log(‘2’),立即執行,查看有無微任務,有一個then的回調函數,立即執行。
5.第一輪宏任務執行結束。
6.開始第二輪宏任務,執行宏任務中的setTimeout函數。
將以上代碼升級下:
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')
答案是不能,因為只有resolve成功回調之后才能執行.then,而現在resolve在setTimeout宏任務中,只有等setTimeout執行完之后才能執行.then中的微任務
解析
1.這段代碼作為宏任務,進入主線程。
2.先遇到等待時間為1000ms的setTimeout,記為s1,并且把這個setTimeout內部的函數推入宏任務的隊列中,下一輪宏任務執行時調用。
3.接下來遇到了Promise,同步代碼立即執行,但其內部包含一個等待時間為100ms的setTimeout,記為s2,并且promise的resolve也在其中,也把它放在下一輪的宏任務中。
4.遇到console.log(‘5’),立即執行。
5.第一輪宏任務執行結束。查看當前有沒有可執行的微任務,沒有則執行宏任務。
6.開啟第二輪宏任務,發現有兩個宏任務,比較等待時間長短,時間短的先執行,先執行s2,發現其中有微任務promise.then,立即執行,再執行s1。
最后的執行順序為2 5 3 4 1
“JavaScript中的事件循環方式是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。