JavaScript 事件循環機制

javascript是一門單線程的非阻塞的腳本語言。單線程意味着javascript在執行代碼的任什麼時候候,都只有一個主線程來處理全部的任務。javascript

那麼javascript引擎是如何實現這一點的呢?java

由於事件循環(event loop)。先上圖:git

event_loop

圖片解讀:github

  • 同步和異步任務分別進入不一樣的執行場所,同步的進入主線程,異步的進入Event Table並註冊函數
  • 當指定的事情完成時(重點)Event Table會將這個函數移入Event Queue
  • 主線程內的任務執行完畢爲空,會去Event Queue讀取對應的函數,進入主線程執行
  • 上述的過程會不斷的重複,也就是經常說的Event Loop(事件循環)

簡單例子

咱們來一個簡單的例子來講明下:promise

console.log('1');
setTimeout(() => {
	console.log('2');
}, 0)
console.log('3');
複製代碼

上面的代碼將輸出下面的結果:bash

1
3
2
複製代碼

由於setTimeout是一個異步的任務,因此會在最後才執行。異步

那麼,咱們來個複雜點的例子:函數

複雜例子

console.log('1');
 setTimeout(() => {
 	console.log('2')
 }, 1000);
 new Promise((resolve, reject) => {
 	setTimeout(() => {
 		console.log('3');
 	}, 0);
 	console.log('4');
 	resolve();
 	console.log('5');
 }).then(() => {
 	console.log('6');
 });
 console.log('7');
複製代碼

上面的代碼輸出的結果是:oop

1
4
5
7
6
3
2
複製代碼

看到這代碼的時候是否是有些蒙圈?在咱們揭開謎底以前,先來了解下微任務和宏任務post

微任務和宏任務

微任務和宏任務都是異步的任務,他們都屬於隊列,主要區別是它們的執行順序--微任務會比宏任務先執行。

宏任務包含有:setTimeout, setInterval, setImmediate, I/O, UI rendering

微任務包含有:process.nextTick, promise.then, MutationObserver

嗯~回到上面的代碼,以下:

console.log('1');
 setTimeout(() => {
 	console.log('2')
 }, 1000);
 new Promise((resolve, reject) => {
 	setTimeout(() => {
 		console.log('3');
 	}, 0);
 	console.log('4');
 	resolve();
 	console.log('5');
 }).then(() => {
 	console.log('6');
 });
 console.log('7');
複製代碼

在執行到new Promise的時候會立馬新建一個promise對象並當即執行。因此會輸出 1,4,5,而then則會在Event Table中註冊成回調函數並放在微任務隊列中,而兩個setTimeout(輸出3)和setTimeout(輸出2,1s後完成的啊)會被前後註冊成回調函數並放在宏任務隊列中。

理解了上面的一些原理以後,咱們再來練下手...

console.log(1)
process.nextTick(() => {
  console.log(8)
  setTimeout(() => {
    console.log(9)
  })
})
setTimeout(() => {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})
let promise = new Promise((resolve,reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()
  console.log(4)
})
fn()
console.log(3)
promise.then(() => {
  console.log(12)
})
function fn(){
  console.log(6)
}
複製代碼

獲得的結果是:

1
4
6
3
8
12
2
11
10
9
複製代碼

客官能夠畫下圖整理下思路,而後代碼運行驗證一下啊💨

參考&後話

文章首發javascript事件循環機制,更多的內容,請戳個人博客進行了解,能留個star就更好了💨

相關文章
相關標籤/搜索