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继续循环。

猜你喜欢

转载自blog.csdn.net/aide315/article/details/79628972