0
点赞
收藏
分享

微信扫一扫

js事件循环的理解

飞空之羽 2022-04-08 阅读 57
javascript

直接上代码

console.log(1)
process.nextTick(() => {
  console.log(8)
  setTimeout(() => {
    console.log(9)
  })
})
setTimeout(() => {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})
requestIdleCallback(() => {
  console.log(7)
})// 特殊说明: new Promise()属于主线程任务
let promise = new Promise((resolve,reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()  // 这个console也属于主线程任务
  console.log(4)
})
fn()
console.log(3)
promise.then(() => {
  console.log(12)
})
function fn(){
  console.log(6)
}

结果是1、4、6、3、12、8、2、11、10、9、7

解析:
js是从上到下执行的,所以上来先打印的是 1 ,继续往下走;

遇见了process.nextTick,因为它属于微队列(microtask),并且当前主线程的代码还没有执行完毕,所以它被展示扔到了微队列里,暂时不打印;

这个时候又遇到了setTimeout,setTimeout是属于宏队列(macrotask);

requestIdleCallback,这里也是不立即执行的,它也不属于任何队列,这里不做详细解释;

promise在实例化的时候,这里的setTimeout继续被丢到了宏队列(macrotask)中,并执行了成功的方法,在有promise.then的调用的时候就会去出发,但这里不做打印,接着发现了console,这里直接打印 4 );

fn函数直接调用,直接打印 6 ;

console,直接打印 3 ;

promise.then因为它属于微队列,但是它在promise实例化的时候被调用了,所以它会在微队列的最前面执行;

到这里主线程里面就没有任何可以执行到东西了,下面开始走微队列(microtask):

由于promise.then被提前调用了,所以它会先执行,打印 12 ;

微队列(microtask)里面还有一个,就是上面的process.nextTick,执行它,打印 8 ,这个时候发现它有一个setTimeout,放到宏队列(macrotask);

到这里微队列就走完了,下面开始走宏队列(macrotask):

最外面的setTimeout在一开始的时候被放了进去,所以先执行它,打印 2 ,发现它里面有promise被实例化,直接执行,打印 11 ;

下一个要走的就是promise里面的setTimeout,打印 10 ;

还剩最后一个setTimeout,就是process.nextTick里面的,打印 9 ;

到这里主线程、宏队列(macrotask)、微队列(microtask)就全都跑完了,在全部跑完的时候,requestIdleCallback才会执行,打印 7 ;

requesIdleCallback会在当前浏览器空闲时期去依次执行,在整个过程当中你可能添加了多个requestIdleCallback,但是都不会执行,只会在空闲时期,去依次根据调用的顺序就执行。

举报

相关推荐

0 条评论