1. 程式人生 > 其它 >js單執行緒--事件執行順序,巨集任務與微任務

js單執行緒--事件執行順序,巨集任務與微任務

技術標籤:佇列javascriptvue

1,js的程式碼執行順序

js引擎執行js程式碼的時候是單執行緒的,同一時刻只會有一個程序執行JS程式碼,多工需要排隊等候。

JavaScript的單執行緒,與它的用途有關,作為瀏覽器指令碼語言,JavaScript的主要用途是與使用者互動,以及操作DOM。這決定了它只能是單執行緒,否則會帶來很多複雜的同步問題。這種模式可能會阻塞程式碼,導致程式碼執行效率低下。

為了避免這個問題,出現了非同步程式設計,通過回撥函式來實現非同步程式碼的存放與執行。將所有的任務分為兩種,一種是同步任務,一種是非同步任務。

  1. 同步任務:在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行下一個任務。
  2. 非同步任務:不進入主執行緒,而進入“任務佇列”的任務,自由“任務佇列”通知主執行緒,某個非同步任務可以執行了,該任務才會進入主執行緒執行。

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

以上就是我的個人理解了,大家再見啦。