JavaScript事件循環(Event Loop)

任務隊列

首先咱們要知道關於JavaScript的一些規則:git

  • JavaScript是被設計成單線程的
  • JavaScript的任務分爲同步任務和異步任務

同步任務都在主線程上執行,造成一個執行棧。當主線程執行完以後,運行微任務(micro-task)隊列的任務直到爲空,更新UI渲染(會根據瀏覽器的邏輯,決定要不要立刻執行更新),而後再運行宏任務(macro-task)隊列的任務直到爲空......流程以下:github

(主線程上的執行棧同步任務,能夠視爲是第一個macro-task隊列)
 macro-task -> micro-task(若是存在) -> 更新UI渲染
複製代碼

如此無限循環上面的流程,是爲JavaScript的Event Loop機制。chrome

宏任務

宏任務(macro-task),宏任務隊列能夠有一個或者多個。每一個任務都有一個任務源(task source),源自同一個任務源的 task 必須放到同一個任務隊列,從不一樣源來的則被添加到不一樣隊列。promise

宏任務:script(全局任務), setTimeout, setInterval, setImmediate, I/O, UI rendering.瀏覽器

微任務

微任務(micro-task),微任務在渲染更新前,macro-task以後執行。 關於async和await,由於async await 自己就是promise+generator的語法糖。因此await後面的代碼是microtask。實際上await是一個讓出線程的標誌。await後面的表達式會先執行一遍,將await後面的代碼加入到microtask中,而後就會跳出整個async函數來執行後面的代碼。bash

微任務:process.nextTick, Promise, Object.observer, MutationObserver,await.異步

舉例

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}

console.log('script start');

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

async1();

new Promise(function (resolve) {
    console.log('promise1');
    resolve();
}).then(function () {
    console.log('promise2');
});
console.log('script end');
複製代碼

流程以下:async

  1. console打印script start
  2. setTimeout,是異步宏任務,進入macro-task setTimeout隊列
  3. async1(), async await函數,在await以前是同步任務,直接執行,打印async1 start
  4. await async2(),await後面的表達式會先執行一遍,打印async2
  5. await 下面的代碼視爲promise.then,進入micro-task promise隊列,跳出async1()
  6. new Promise,promise內,.then以前的代碼是直接執行的,因此打印promise1
  7. .then內函數進入micro-task promise隊列後
  8. console,直接打印script end
  9. 主線程執行棧運行完並清空了,micro-task進入執行棧,分別按順序執行打印async1 endpromise2
  10. micro-task隊列清空,macro-task進入執行棧,打印setTimeout,程序運行完畢。

完整結果以下:函數

/**
 *script start
 *async1 start
 *async2
 *promise1
 *script end
 *async1 end
 *promise2
 *setTimeout
 */
複製代碼

該結果基於chrome 版本 72.0.3626.121。由於async await標準有所改變,因此稍老版本的瀏覽器結果可能不一致。oop

參考以下:

jakearchibald.com/2015/tasks-… github.com/Advanced-Fr…

相關文章
相關標籤/搜索