【面試】JS執行機制

參考:這篇文章的總結promise

由於JS有同步任務和異步任務,就形成了JS多線程的假象,可是JS是一門單線程語言多線程

JS的執行機制是根據事件循環的順序。異步

宏任務和微任務

由於JS有同步任務和異步任務,爲了瞭解執行機制,將任務細分爲宏任務和微任務。post

  • macro-task(宏任務):包括總體代碼script,setTimeout,setIntervalui

  • micro-task(微任務):Promise,process.nextTickspa

宏任務和微任務還包括其餘的,這裏不贅述線程

事件循環

事件循環的順序就是:code

  1. 進入總體代碼(宏任務)後,開始第一次循環。
  2. 接着執行全部的微任務
  3. 而後再次從宏任務開始,找到其中一個任務隊列執行完畢
  4. 再執行全部的微任務

注意

第一次進入總體代碼時,就將當即執行的執行了,有宏任務就放入宏任務隊列,有微任務放入微任務隊列。隊列

此時有沒執行的宏任務和微任務,可是由於剛剛執行了宏任務(總體代碼),因此此次循環要執行微任務,而且每次執行微任務都要執行全部的微任務事件

執行完此次全部的微任務,就循環去執行宏任務。記住除了第一次,之後再執行宏任務都只執行一個宏任務

若是又有微任務,就再去循環執行全部的微任務……再去循環執行一個宏任務……執行全部的微任務……執行一個宏任務……

例子

舉一個小例子

setTimeout(function() {
  console.log('setTimeout');
});

new Promise(function(resolve) {
  console.log('promise');
  resolve();
}).then(function() {
  console.log('then');
});
console.log('console');


複製代碼
promise
console
then
setTimeout
複製代碼

解析

  1. 第一次循環總體代碼(宏任務),new Promise當即執行,輸出promise

    console.log('console')也當即執行,輸出console

    此次循環後宏任務隊列有:setTimeout

    微任務隊列有:promise的.then

  2. 第二次循環要執行全部的微任務了,即promise的.then,輸出then

  3. 第三次循環要執行一個宏任務了,即setTimeout,輸出setTimeout

總結

只要記住

  1. 循環執行全部的宏任務……執行一個微任務……全部的宏任務……一個微任務
  2. 第一次循環執行的總體代碼屬於宏任務
相關文章
相關標籤/搜索