一道題引起的EventLoop思考

題目背景

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'); 
複製代碼

題目的本質,是考察setTimeoutpromiseasync await的實現順序及JS的時間循環方面的相關問題。javascript

結果爲: script start async1 start async2 promise1 script end async1 end promise2 settimeoutjava

這裏涉及到同步異步MicrotasksMacrotasksMicrotasks優先級別高於Macrotasks 其中MicrotasksMacrotasks分別是:promise

microtasks:

  • process.nextTick
  • promise
  • Object.observe
  • MutationObserver

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI渲染
  1. 一個事件循環(event loop)會有一個或多個任務隊列(task queue)
  2. task queue 就是 macrotask queue
  3. 每個 event loop 都有一個 microtask queue
  4. task queue == macrotask queue != microtask queue
  5. 一個任務 task 能夠放入 macrotask queue 也能夠放入 microtask queue 中

所以事件循環的順序,決定了JavaScript代碼的執行順序。它從script(總體代碼)開始第一次循環。以後全局上下文進入函數調用棧。直到調用棧清空(只剩全局),而後執行全部的micro-task。當全部可執行的micro-task執行完畢以後。循環再次從macro-task開始,找到其中一個任務隊列執行完畢,而後再執行全部的micro-task,這樣一直循環下去。瀏覽器

定時器是怎麼實現定時的?爲何會出現不定時的狀況?

首先,要明確的一點:javascript是以單線程的方式運行的。JavaScript的主要用途是與用戶互動,以及操做DOM。若以多線程的方式,則可能出現衝突。假設有兩個線程同時操做一個DOM元素,線程1要求瀏覽器刪除DOM,而線程2卻要求修改DOM樣式,這時瀏覽器就沒法決定採用哪一個線程的操做。固然,咱們能夠爲瀏覽器引入「鎖」的機制來解決這些衝突,但大大提升複雜性,因此 JavaScript從誕生開始就選擇了單線程執行。在某一時刻內只能執行特定的一個任務,而且會阻塞其它任務執行。 可是JavaScript 有個基於「Event Loop」併發的模型(不是並行)。前者是邏輯上的同時發生,然後者是物理上的同時發生。因此,單核處理器也能實現併發。 上圖說明一下併發和並行:bash

佔用

小tips:多線程

console.log(1);
setTimeout(function(){
    console.log(2);
    Promise.resolve(1).then(function(){
        console.log('ok')
    })
})
setTimeout(function(){
    console.log(3)
})
複製代碼

分析:先默認走棧,輸出1。此時並無微任務,因此微任務不會執行。先走第一個setTimeout,輸出2,同時將微任務放到隊列中,執行微任務,輸出ok,微任務執行完,再走宏任務,輸出3。併發

Node.js的Event Loop

V8引擎解析JavaScript腳本。 解析後的代碼,調用Node API。 libuv庫負責Node API的執行。它將不一樣的任務分配給不一樣的線程,造成一個Event Loop(事件循環),以異步的方式將任務的執行結果返回給V8引擎。 V8引擎再將結果返回給用戶。異步

淺談event loopasync

相關文章
相關標籤/搜索