js單執行緒--事件執行順序,巨集任務與微任務
阿新 • • 發佈:2021-01-15
技術標籤:佇列javascriptvue
1,js的程式碼執行順序
js引擎執行js程式碼的時候是單執行緒的,同一時刻只會有一個程序執行JS程式碼,多工需要排隊等候。
JavaScript的單執行緒,與它的用途有關,作為瀏覽器指令碼語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單執行緒,否則會帶來很多複雜的同步問題。這種模式可能會阻塞程式碼,導致程式碼執行效率低下。
為了避免這個問題,出現了非同步程式設計,通過回撥函式來實現非同步程式碼的存放與執行。將所有的任務分為兩種,一種是同步任務,一種是非同步任務。
- 同步任務:在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行下一個任務。
- 非同步任務:不進入主執行緒,而進入“任務佇列”的任務,自由“任務佇列”通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。
2,為什麼會有非同步
如果程式碼只能自上而下執行,如果上一行解析時間很長,那麼下面的程式碼就會被阻塞。使用者就會想"這麼卡,算了不用了",這樣就導致了很差的使用者體驗。而使用非同步程式設計就會將任務新增到任務佇列中,優先執行同步程式碼,將回調函式或者比較難載入的放到佇列中,就會節省很多時間。
3,任務佇列的執行順序
由於非同步函式中還有微任務與巨集任務,
巨集任務:整體程式碼script、setTimeOut、setInterval、互動事件 微任務:promise.then、process.nextTick(node)、MutaionObserver
先微任務microtask佇列,再巨集任務macrotask佇列 。
呼叫Promise 中的resolve,reject屬於微任務佇列,setTimeout屬於巨集任務佇列 ,所以:同步=>非同步:微任務=>巨集任務
例如:
console.log('event start')
setTimeout(function () {
console.log('setTimeout');
});
new Promise(function(resolve,reject){
console.log('promise start')
resolve()
}).then (function(){
console.log('promise end')
})
console.log('event end')
//執行結果:
event start
promise start
event end
promise end
undefined
setTimeout
注意:new Promise是會進入到主執行緒中立刻執行,而promise.then則屬於微任務。
4,簡單練習:
下面是一些例子:
//先來個簡單的:
console.log(1)
setTimeout(function(){
console.log(2)
},0)
console.log(3)
列印結果為:
1 3 2
//關於非同步的:
setTimeout(()=>{
console.log('setTimeout1')
},0)
let p = new Promise((resolve,reject)=>{
console.log('Promise1')
resolve()
})
p.then(()=>{
console.log('Promise2')
})
列印結果為:
Promise1 Promise2 setTimeout1
//簡單練習:
console.log("start")
Promise.resolve().then(()=>{
setTimeout(()=>{
console.log(1)
},0)
onsole.log(2)
}).then(()=>{
console.log(3)
})
console.log(4)
setTimeout(()=>{
console.log(5)
},0)
// process.nextTick(()=>{
// console.log(6)
// })
console.log("end")
//執行順序為:
start 4 end 2 3 5 1
以上就是我的個人理解了,大家再見啦。