JS事件循环中的宏任务和微任务执行顺序

1. 宏任务和微任务事件

其中微任务的优先级高于宏任务,括号内为事件运行环境

宏任务微任务
I/O事件/onClick点击事件process.netTick (Node)
setTimeoutNutationObserver(浏览器)
setImmediate(Node)Promise
setInterval
requestAnimationFrame(浏览器)
2. 优先级更清晰的版本

idle观察者 > I/O观察者 > check观察者

观察者观察事件
idle观察者process.netTick
I/O观察者一般性的I/O回调,如:网络,文件数据库I/O等
check观察者setTimeout,setImmediate
3. 详解setTimeout和setImmediate优先级

事件在浏览器中的常见概念的eventLoop和Node环境中的循环事件大致相同,最大的不同Node中事件循环分不同的阶段详情戳链接

这两个事件同时存在仅有可能运行在node环境中,下图为node事件循环不同阶段示意图:
在这里插入图片描述

setTimeout(() => {
    console.log('setTimeout');
}, 0);
setImmediate(() => {
    console.log('setImmediate');
})
// 输出有两种情况
// setImmediate
// setTimeout
// 或者
// setImmediate
// setTimeout

为什么会这样子呢?

这里我们要根据前面的那个事件循环不同阶段的图解来说明一下:

首先进入的是timers阶段,如果我们的机器性能一般,那么进入timers阶段,一毫秒已经过去了(setTimeout(fn, 0)等价于setTimeout(fn, 1)),那么setTimeout的回调会首先执行。

如果没有到一毫秒,那么在timers阶段的时候,下限时间没到,setTimeout回调不执行,事件循环来到了poll阶段,这个时候队列为空,此时有代码被setImmediate(),于是先执行了setImmediate()的回调函数,之后在下一个事件循环再执行setTimemout的回调函数。

而我们在执行代码的时候,进入timers的时间延迟其实是随机的,并不是确定的,所以会出现两个函数执行顺序随机的情况。

以下两种情况setImmediate永远先于setTimeout执行:

var fs = require('fs')

fs.readFile(__filename, () => {
    setTimeout(() => {
        console.log('timeout');
    }, 0);
    setImmediate(() => {
        console.log('immediate');
    });
});
setTimeout(() => {
    setImmediate(() => {
        console.log('setImmediate');
    });
    setTimeout(() => {
        console.log('setTimeout');
    }, 0);
}, 0);
4. 详解process.nextTick() 和 Promise优先级

对于这两个,我们可以把它们理解成一个微任务。也就是说,它其实不属于事件循环的一部分。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值