js 宏任务与微任务

宏任务:计时器 ajax 读取文件等

微任务:promise等

执行顺序:
1、同步程序
2、process.nextTick(Node.js 环境)
3、微任务
4、宏任务
5、setImmediate

	setImmediate(()=>{
		console.log(1)
	})
	console.log(2)
	setTimeout(()=>{console.log(3)},0)
	setTimeout(()=>{console.log(4)},100)
	console.log(5)
	new Promise((resolve)=>{
		console.log(6)  // 内部是同步的
		resolve()
	}).then(()=>{
		console.log(7) // then是放到任务队列里的 是异步的
	})
	// 输出顺序为 2、5、6、7、1、3、4
	// 有时也会出现2、5、6、7、3、1、4
关于setTimeout和setImmediate

setTimeoutsetImmediate在Node环境下执行是靠“随缘法则”的。

为什么会这样子呢?

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

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

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

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

var fs = require('fs')

fs.readFile(__filename, () => {
    setTimeout(() => {
        console.log('timeout');
    }, 0);
    setImmediate(() => {
        console.log('immediate');
    });
});

这里setImmediate永远先于setTimeout执行

原因:fs.readFile的回调是在poll阶段执行的,当其回调执行完毕之后,poll队列为空,而setTimeout入了timers的队列,此时有代码被setImmediate(),于是事件循环先进入check阶段执行回调,之后在下一个事件循环再在timers阶段中执行有效回调。

  • 如果两者都在主模块中调用,那么执行先后取决于进程性能,也就是随机。
  • 如果两者都不在主模块调用(被一个异步操作包裹),那么setImmediate()的回调永远先执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值