js事件的執行機制(eventloop)


一、js的內存模型

 

 

 

二、js代碼執行機制:

  • 所有同步任務都在主線程上的棧中執行。

  • 主線程之外,還存在一個"任務隊列"(task queue)只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件

  • 一旦"棧"中的所有同步任務執行完畢,系統就會讀取"任務隊列",選擇出需要首先執行的任務(由瀏覽器決定,並不按序)。

三、宏任務與微任務:

  1. MacroTask(宏觀Task) setTimeout, setInterval, , requestAnimationFrame(請求動畫), I/O

  2. MicroTask(微觀任務) process.nextTick, Promise, Object.observe, MutationObserver

  3. 先同步 再取出第一個宏任務執行 所有的相關微任務總會在下一個宏任務之前全部執行完畢 如果遇見 就 先微后宏

 

案例一:(在主線程上添加宏任務)

    console.log(1)
    setTimeout(function () {
      console.log(2);
    },0)
    console.log(3)  //1 3 2

先看代碼:一個打印,一個定時器,一個打印

因為定時器是異步操作,又是宏任務,所以先執行第一個打印,接着將setTimeout放入宏任務隊列,接着執行第二個打印再執行宏任務隊列中的setTimeout

案例二:(在主線程上添加微任務)

   console.log(1)
    new Promise(function(resolve,reject){
        console.log('2')
        resolve()
    }).then(function(){
      console.log(3)
    })
    console.log(4)  //1 2 4 3

先看代碼:一個打印,一個new promise,一個promise.then,一個打印

因為new promise會立即執行,promise.then是異步操作且是微任務

所以,先執行第一個打印,執行new Promise將promise.then放入微任務隊列接着執行第二個打印,再執行微任務隊列中的promise.then

案例三:(紅任務中創建微任務)

   console.log('1');
    
    setTimeout(function () {
      console.log('2');
      new Promise(function (resolve) {
        console.log('3');
        resolve();
      }).then(function () {
        console.log('4')
      })
    },0)
  
    new Promise(function (resolve) {
      console.log('5');
      resolve();
    }).then(function () {
      console.log('6')
    })

    setTimeout(function () {
      console.log('7');
      new Promise(function (resolve) {
        console.log('8');
        resolve();
      }).then(function () {
        console.log('9')
      })
      console.log('10')
    },0)
   
    console.log('11')  
// 1  5 11 6 2 3  4 7 8  10 9

先看代碼:一個打印,第一個定時器,一個new promise,一個promise.then,第二個定時器,一個打印

定時器是異步操作,又是宏任務,promise.then是異步操作且是微任務

所以,先執行第一個打印(1),將第一個定時器放入宏任務隊列,執行new Promise(5),將promise.then放入微任務隊列,將第二個定時器放入宏任務隊列,執行打印(11);

主線程上的代碼執行完畢后,看是否有微任務?此時:微任務隊列中有一個promise.then,執行它(6);微任務執行完畢看宏任務隊列;

此時宏任務隊列中兩個定時器,延時都是0秒,所以按順序執行就ok,先執行第一個定時器

第一個定時器中:一個打印,一個mew promise,一個promise.then(微任務);(宏任務中包含微任務,一定要將宏任務中的微任務執行完,再去執行下一個宏任務)

      先執行打印(2),再執行new promise(3),再執行promise.then(4);第一個宏任務執行完,執行第二個宏任務(第二個定時器)

第二個定時器中:一個打印,一個new promise,一個promise.then(微任務),一個打印

      先執行第一個打印(7),再執行new promise(8),再執行第二個打印(10),在執行promise.then(9) 

案例四:(微任務中創建宏任務)

 

   new Promise((resolve) => {
      console.log("1")
      resolve()
    }).then(() => {
      console.log("2")
      setTimeout(() => {
        console.log("3")
      },0)
    })
    setTimeout(() => {
      console.log("4")
    },1000)
    console.log("5")  //1 5 2 3 4 

 

先看代碼:一個new promise,(一個then,一個定時器(0秒)),一個定時器(1秒),一個打印 微任務中有宏任務,則將宏任務放入宏任務隊列任務中

先執行new promise(1),再將promise.then放入微任務隊列,將定時器放入宏任務隊列(0秒),將定時器放入宏任務隊列(1秒),執行打印(5)

接着看微任務隊列,執行promise.then(2);微任務隊列中都執行完再看宏任務隊列

宏任務隊列中兩個定時器,一個延時0秒,一個延時1秒,所以先執行延時0秒的那個

第一個定時器:執行(3);

第二個定時器:執行(4)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM