1. 程式人生 > >Javascript 事件迴圈(Event Loop)

Javascript 事件迴圈(Event Loop)

規則同一時間只有一個任務在執行,同時執行的過程不能被中途打斷

事件佇列型別:macrotask queue 和microtask queue

常見的macrotask 和 microtask 如下 :

macrotask queue : 
    Mouse Event
    Keyboard Event
    Network Event
    HTML Parsing
    setTimeout
    setInterval
    setImmediate
    I/O
    
microtask queue : 
    DOM mutations
    Promise
    Object.observe
    process
.nextTick

從分類對應的事件處理來看,macrotask 處理的是耗時比較長的,而 microtask 處理是耗時短的。奇怪的是這兩個詞看起來比較像,一個是mac-rotask ,另一個是 mic-rotask 就只差了一個字母, 它們分別對應的單詞意思表達為:macrotask(表示巨集觀的)和microtask(表示微觀的)

示例如下 :
    console.clear();
    console.log('========== START ==========');
    
    Part-1:
    var interval = setInterval(() =>
console.log('setInterval'), 0) setTimeout(()=>console.log('setTimeout 1'),0) setTimeout(()=>console.log('setTimeout 2'),0) Part-2: setTimeout(() => { console.log('setTimeout 3') Promise.resolve() .then(() => { console.log('promise 1') }) .then(()
=>
{ console.log('promise 2') }) .then(() => { setTimeout(() => { console.log('setTimeout 4') Promise.resolve() .then(() => { console.log('promise 3') }) .then(() => { console.log('promise 4') }) .then(() => { setTimeout(() => { console.log('setTimeout 5') Promise.resolve() .then(() => { console.log('promise 5') }) .then(() => { console.log('promise 6') }) .then(() => { clearInterval(interval) console.log('========== END ==========') }) }, 10) }) }, 0) }) }, 0) Part-3Promise.resolve() .then(() => { console.log('promise 7') }) .then(() => { console.log('promise 8') }) console.log('========== CONTINUE ==========')

其邏輯結構如下:


    =>  START
        
        Part-1:
        setInterval
        setTimeout
        setTimeout
        
        Part-2:
        setTimeout
            Promise => then
                    => then 
                    => then 
                        => setTimeout
                            Promise => then 
                                    => then
                                    => then
                                        => setTimeout
                                            Promise => then
                                                       then 
                                                       then
                                                        clearInterval
                                                        END
        Part-3:                            
        Promise => then 
                => then
                    
        CONTINUE
        

結果顯示如下:

    Console was cleared
    EventLoop:3 ========== START ==========
    EventLoop:60 ========== CONTINUE ==========
    EventLoop:49 promise 7
    EventLoop:52 promise 8
    EventLoop:1 undefined
    EventLoop:4 setInterval
    EventLoop:9 setTimeout 3
    EventLoop:12 promise 1
    EventLoop:15 promise 2
    2EventLoop:4 setInterval
    EventLoop:19 setTimeout 4
    EventLoop:22 promise 3
    EventLoop:25 promise 4
    3EventLoop:4 setInterval
    EventLoop:29 setTimeout 5
    EventLoop:32 promise 5
    EventLoop:35 promise 6
    EventLoop:39 ========== END ==========
    EventLoop:6 setTimeout 2
    EventLoop:5 setTimeout 1

那如果把Part-1移動到Part-3後面結果會是怎麼的呢?答案是,保持與上面一致執行過程是怎樣控制的?首先要理解上面提到的規則,其次記住事件佇列的分類(macrotask和microtask),同時還需要記住對應佇列下的事件型別。本文由:北大青鳥學校開發小組提供

  • 在一個事件迴圈週期中一個任務的開始是從 macrotask 佇列開始執行的,當一個 macrotask 執行結束後,microtasks 佇列中的任務將一個個被執行,在 microtask 執行時還可以加入多個 microtask (事件巢狀處理),直到 microtask 佇列清空,然後又回到macrotask繼續迴圈。