EventLoop二三事

mybydhn醬發表於2018-09-12

瀏覽器中的EventLoop

嘿,你覺得下面的程式碼執行結果是什麼呢?

console.log('start')

setTimeout( function () {
  console.log('setTimeout')
}, 0 )

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('end')
複製程式碼

可以先嚐試進行如下分析

1.先將同步執行的程式碼找出,首先列印的一定是start end

2.setTimeout、Promise是否有優先順序 還是根據順序來執行?

執行一下程式碼,答案是:start、end、promise1、promise2、setTimeout

需要理解的知識點

1.執行棧

javascript是單執行緒,也就是隻有一個主執行緒,主執行緒有一個棧,每一個函式執行時都會生成新的execution context(執行上下文),執行上下文會包含一些當前函式的引數、區域性變數之類的資訊,它會被推入棧中,running execution context(正在執行的上下文)始終處於棧的頂部。當函式執行完後,它的執行上下文會從棧彈出

EventLoop二三事
粟子:

function bar(){
    console.log('bar')
}
function foo(){
    console.log('foo');
    bar();
}
foo();
複製程式碼

執行過程中棧的變化:

EventLoop二三事

2.巨集任務 setTimeout、setImmediate

微任務 promises、processs.nextTick、MutationObserver

3.整個最基本的Event Loop如圖所示

  • queue可以看做一種資料結構,用以儲存需要執行的函式
  • setTimeout註冊的函式,等到期後進入task佇列
  • 其餘API註冊函式直接進入自身對應的macrotask/microtask佇列
  • Event Loop繼續檢查microtask佇列是否為空,依次執行直至清空microtask佇列
  • 執行macrotask佇列

EventLoop二三事

Node中的EventLoop

Node.js也是單執行緒的Event Loop,但是它的執行機制不同於瀏覽器環境

EventLoop二三事

根據上圖,Node.js的執行機制如下

1.V8引擎解析javascript指令碼 2.解析後的程式碼 呼叫node API 3.libuv庫負責Node API的執行。它將不同的任務分配給不同的執行緒,形成一個Event Loop(事件迴圈),以非同步的方式將任務的執行結果返回給V8引擎 4.V8引擎再將結果返回給使用者

整個最基本的Event Loop 如圖所示

EventLoop二三事

練習

setTimeout(()=>{
    console.log('timeout1')
    Promise.resolve().then(data=>{
        console.log('promise2')
    })
})
Promise.resolve().then(()=>{
    console.log('promise1')
    setTimeout(()=>{
        console.log('timeout2')
    })
})
複製程式碼
let fs = require('fs')
fs.readFile('a.txt','utf-8',()=>{
    setTimeout(()=>{
        console.log('timeout2')
    },0)
    setImmediate(()=>{
        console.log('setImmediate')
    })
})
複製程式碼

執行一下吧 看下結果是否你想的呢???

相關文章