js事件循環 eventloop

1.什麼是事件循環?

JavaScript有一個基於事件循環的併發模型,事件循環負責執行代碼、收集和處理事件以及執行隊列中的子任務。這個模型與其它語言中的模型截然不同,比如 C 和 Java。這是來自MDN的介紹。
簡單來講就是js運行處理代碼的一套機制。

2.微任務Microtasks和宏任務tasks

宏任務:一般是指js引擎宿主環境發生通信產生的回調任務,常見的宏任務有run <script>(同步的代碼執行)、setTimeoutsetIntervalsetImmediate(node環境中)、I/OUI交互

微任務:一般是宏任務在線程中執行產生的回調,常見的微任務有PromiseMutationObserverprocess.nextTick(node環境)。

3.執行流程

執行流程
簡單來講就是在宏任務中,先執行一遍,遇見微任務,將微任務推到隊列,再執行所有微任務。拿簡單的代碼舉例

<script>
(function() {
	console.log('start');
	setTimeout(function() {
	  console.log('setTimeout1');
	});
	Promise.resolve().then(function() {
	  console.log('promise1');
	})
	setTimeout(function() {
	  console.log('setTimeout2');
	}, 0);
	console.log('end');
})();
</script>

首先執行第一個宏任務run script,執行裏邊的匿名函數。首先打印start,遇見setTimeout推入到宏任務隊列,再遇見Promise推到微任務隊列,再遇見setTimeout推到宏任務隊列,打印end。目前的隊列如圖:

宏任務 微任務
setTimeout Promise
setTimeout

當前的微任務還沒執行完畢所以執行Promise,打印promise1;然後再執行下一個宏任務setTimeout打印出setTimeout1,因爲這個宏任務中沒有微任務,所以接着執行下一個宏任務setTimeout,打印出setTimeout2

再來一個頭條的異步筆試題,你要是能答對這個,相信事件循環機制就已經掌握了。

<script>
	async function async1() {
	    console.log('async1 start');
	    await async2();
	    console.log('async1 end');
	}
	async function async2() {
	    console.log('async2');
	}
	console.log('script start');
	setTimeout(function() {
	    console.log('setTimeout');
	}, 0)
	async1();
	new Promise(function(resolve) {
	    console.log('promise1');
	    resolve();
	}).then(function() {
	    console.log('promise2');
	});
	console.log('script end');
</script>

不懂得地方可以去翻看執行流程或者留言,這道題的答案是:script start、async1 start、async2、promise1、script end、async1 end、promise2、setTimeout。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章