瀏覽器中的Event Loop

首先咱們要知道瀏覽器是由什麼組成的javascript

1.js主線程

1.1.heap(堆)

  • 堆:由操做系統自動分配釋放 ,存放函數的參數值,局部變量的值等。特色先進後出(數組的shift方法)
let arr = [];
    arr.push(1);
    arr.push(2);
    console.log(arr.shift());   // 1
複製代碼

1.2.stack(棧)執行上下文

  • 棧:會自動分配內存空間,會自動釋放,存放基本類型,簡單的數據段,佔據固定大小的空間 特色先進後出(函數執行的銷燬過程)
  • 當前棧也叫執行上下文(執行同步任務)

同步任務:在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;java

alert("不關閉後面是不會執行的");
    console.log(1);
複製代碼

2.WebAPIs (DOM,ajax,setTimeout)

3.callback queue(回調/任務 隊列)

3.1任務隊列的特色:先進先出,先放進去的異步任務先執行

setTimeout(()=>{
    console.log(1);
},300)
setTimeout(()=>{
    console.log(3);
},200)
setTimeout(()=>{
    console.log(2);
},200)
- 輸出的結果是 3 2 1
複製代碼

3.2任務隊列裏面存放的是異步任務(宏任務,微任務)

異步任務:不進入主線程、而進入"任務隊列"的任務,只有"任務隊列"通知主線程,某個異步任務能夠執行了,該任務纔會進入主線程執行。node

for(var i = 0; i < 5; i++){
        setTimeout(() =>console.log(i), 0);
    }
    console.log("ok");
    // 先輸出ok,再輸出5個5
複製代碼
3.1.1異步任務的分類
  • 1.macro-task(宏任務): setTimeout, setInterval, setImmediate(ie), I/O MessageChannel
  • 2.micro-task(微任務): process.nextTick, 原生Promise,Object.observe(已廢棄),MutationObserver(h5的一個方法,在dom更新完以後執行)
3.1.2異步任務的執行順序

微任務的執行順序在宏任務以前ajax

setTimeout(()=>{
    console.log("setTimeout1");
},0)
Promise.resolve().then(()=>{
    console.log("Promise");
})
process.nextTick(()=>{
    console.log("nextTick");
})
// 輸出 nextTick Promise setTimeout1
複製代碼

經過上面的瞭解咱們大體知道瀏覽器是先執行同步任務,執行完以後再執行異步任務。數組

回到主題,咱們來看看瀏覽器是怎麼實現一個事件環(for)的

  • 1.全部同步任務都在主線程上執行,造成一個執行棧瀏覽器

  • 2.主線程以外,還存在一個任務隊列。只要異步任務有了運行結果,就在任務隊列之中放置一個事件dom

  • 3.一旦執行棧中的全部同步任務執行完畢,系統就會讀取任務隊列,將隊列中的事件放到執行棧中依次執行異步

  • 4.主線程從任務隊列中讀取事件,這個過程是循環不斷的函數

    整個的這種運行機制又稱爲Event Loop(事件循環)
    複製代碼

看下面一段代碼oop

setTimeout(function(){
    console.log('setTimeout1');
    Promise.resolve().then(()=>{
        console.log('then1');
    });
},0)
Promise.resolve().then(()=>{
    console.log('then2');
    Promise.resolve().then(()=>{
        console.log('then3');
    });
    setTimeout(function(){
        console.log('setTimeout2');
    },0)
})
// 輸出結果 then2 then3 setTimeout1 then1 setTimeout2
複製代碼

咱們得出一個結果

瀏覽器的事件環和任務隊列裏面微任務和宏任務的關係

  • 先執行棧中的內容 執行後 清空微任務
  • 取一個宏任務 再去清空微任務 ,再去取宏任務,一直到任務隊列中沒有爲止

最後再說一下,node的事件環和任務隊列裏面微任務和宏任務的關係

  • 本質上和瀏覽器的事件環不變就是隊列中微任務和宏任務的執行順序有些差異
  • 先執行棧中的內容 執行後 清空微任務
  • 清空宏任務 再去清空微任務 ,再去清空宏任務,一直到任務隊列中沒有爲止
相關文章
相關標籤/搜索