同步 & 非同步(2) - event loop & macro / micro task


Posted by TempuraEngineer on 2022-06-23

目錄


Javascript 與 call stack

Javascript是個單執行緒的語言,它只有一個call stack,所以一次只做一件事

Javascript會用call stack的方式來管理execution contexts(執行環境),call stack會以後進先出的方式執行裡面的任務

stack是有容量限制的,容量取決於執行環境。如果execution contexts的數量大於stack的容量就會發生stack overflow

// 這種遞迴方式就會導致stack overflow

function foo(){
    foo();
}

// Uncaught RangeError: Maximum call stack size exceeded


execution contexts & event queue & event loop

Javascript會建立2種執行環境 - global execution, function execution contexts。

  • global execution
    全域執行環境。在script執行時建立。以瀏覽器來說就是建立window與this

  • function execution contexts
    函示執行環境,即scope的概念。在函式被呼叫時建立,所以可能有多個

如果是同步函式的話丟進call stack(main thread),然後每個函式由上而下一行一行執行code,非同步函式的話等web API解析完先丟到event queue,當JS主執行環境任務全執行完(即call stack空了),會到event queue拿一個來執行。event loop即不斷重複前述動作


macro task(宏任務) & micro task(微任務)

兩者都是非同步任務

javascript-browser-event-loop

  • 宏任務

    • A task is any JavaScript code which is scheduled to be run by the standard mechanisms such as initially starting to run a program, an event callback being run, or an interval or timeout being fired. These all get scheduled on the task queue

    • call stack、micro task的event queue都空了後執行
    • 解析HTML、產生DOM、畫面渲染、載入script、setTimeout、setInterval、鍵盤事件、滑鼠事件、network events
  • 微任務

    • A microtask is a short function which is executed after the function or program which created it exits and only if the JavaScript execution stack is empty, but before returning control to the event loop being used by the user agent to drive the script's execution environment.

    • call stack空了後執行
    • 變更DOM、重新渲染畫面、Promise的then、catch(Promise的executor是同步任務)


執行順序

產生DOM、畫面渲染、載入script(宏任務) →同步任務 → 微任務 → 宏任務

// 帶有async的function事實上還是同步函式
// async只意味著該函式內的動作會返回一個Promise物件
async function sayHello(){ 
    console.log('say');

    // 執行到await會暫停,web API解析完就丟到micro task queue,同步任務結束再執行
    await Promise.resolve(); // 微任務,
    console.log('hello');
}

function foo(){ // 同步任務
    console.log('foo');
}

console.time();
setTimeout(() => { // 宏任務
    console.log('setTimeout');
}, 100)
console.timeEnd();
sayHello();
foo();

// 執行結果如下
// say
// foo
// hello
// setTimeout


🖊名詞解釋

名詞 解釋 其他
call stack(execution stack) 一種資料結構,遵循後進先出的原則。可以想成一個裝了要執行的函式的容器
event queue(task queue、callback queue) 一種資料結構,遵循先進先出的原則。可以想成一個裝了待執行的非同步函式的容器 宏任務、微任務各自裝到不同的event queue
main thread 處理同步任務的thread,大約等於call stack


📖參考資料

Day13 - Event Queue & Event Loop 、Event Table
所以說event loop到底是什麼玩意兒?
透過程式範例,熟悉 JS 執行流程的關鍵:Event Loop

解釋 Event Loop ( 下 ) --- Task Queue ( Callback Queue )
Javascript 的執行環境 (Execution context) 與堆疊 (Stack)
JavaScript Call Stack

Using microtasks in JavaScript
JS 時間循環 - 宏任務與微任務
What are Micro tasks and Macro tasks in JavaScript?
Understand once-the macro tasks and micro tasks of the JS event loop
async and tasks


#micro task #macro task #Event Loop #微任務 #宏任務 #事件循環







Related Posts

滲透測試重新打底(4)--Exploitation初介紹與密碼爆破

滲透測試重新打底(4)--Exploitation初介紹與密碼爆破

篩選方法- map( ), filter( ), find( ), some( )

篩選方法- map( ), filter( ), find( ), some( )

JS30 Day 12 筆記

JS30 Day 12 筆記


Comments