← Back Home

事件循环

  1. JavaScript

本文记录对事件循环的理解

setTimeout与setInterval

不同点:

setTimeout(function() {
	setTimeout(repeatMe, 10);
}, 10);

setInterval(function() {
	
}, 10)

setTimeout要在前一个callback回调执行结束并延迟10ms以后,才能再次执行setTimeout(), 而setInterval()则是每隔10ms就尝试执行callback回调,而不关注上一个callback是何时执行的。

任务队列macrotask与microtask

事件循环中的任务队列主要包括macrotask与microtask,执行的顺序为:

  1. 在 macrotask 队列中执行最早的那个 task ,然后移出
  2. 执行 microtask 队列中所有可用的任务,然后移出
  3. 下一个循环,执行下一个 macrotask 中的任务 (再跳到第2步)

macrotask主要有setInterval与setTimeout,miscrotask主要有Promise.then()的回调。mascrotask产生的microtask可以在本次循环执行,而macrotask则需要下次循环执行。

示例

console.log('start')

const interval = setInterval(() => {  
  console.log('setInterval')
}, 0)

setTimeout(() => {  
  console.log('setTimeout 1')
  Promise.resolve()
      .then(() => {
        console.log('promise 3')
      })
      .then(() => {
        console.log('promise 4')
      })
      .then(() => {
        setTimeout(() => {
          console.log('setTimeout 2')
          Promise.resolve()
              .then(() => {
                console.log('promise 5')
              })
              .then(() => {
                console.log('promise 6')
              })
              .then(() => {
                clearInterval(interval)
              })
        }, 0)
      })
}, 0)

Promise.resolve()
    .then(() => {  
        console.log('promise 1')
    })
    .then(() => {
        console.log('promise 2')
    })

以上代码的输出结果? 首次执行setTimeout、setTimeout,作为一个macrotask,将其回调函数放入自己的队列之中。在下一次循环中执行回调 其次会执行microtask。 重复以上步骤,输出: promise 1 promise 2 setInterval setTimeout 1 promise 3 promise 4 setInterval setTimeout 2 promise 5 promise 6

comments powered by Disqus