关于setTimeout / setImmediate / process.nextTick的区别

有这样一道面试题, 阅读如下代码, 请说出输出顺序

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

setImmediate(() => {

console.log(2);

});

setTimeout(() => {

console.log(3);

}, 0);

process.nextTick(() => {

console.log(4);

});

console.log(1);

答案是 1432, 与你预期的结果符合吗?

解析

首先, setImmediate, setTimeout, process.nextTick 均为异步操作, 而 console.log(1) 是同步, 所以一定在它们三个之前.

然后分析 setImmediate, setTimeout, process.nextTick 三者的区别:

  • setImmediate(callback[, ...args]): callback 将在所有 I/O 事件处理完毕后执行, 多次使用 setImmediate 将会按顺序执行
  • setTimeout(callback, delay[, ...args]): callback 将在 delay 时间后执行, 实际上并不会精确的在 delay 时间调用, 只会保证在 delay 时间立即添加到事件队列队尾
  • process.nextTick(callback[, ...args]): callback 将会插入到事件队列的队首, 如果在当前正有事件被处理, 则处理结束后调用; 如果没有则立即调用

简单来讲, setImmediate是在空闲时间触发, setTimeout是在指定时间后的下一个空闲时间触发, process.nextTick是一种插队的方法, 当前处理完毕后立刻触发

回头我们再来看这道面试题, 1是同步的因此第一个输出, process.nextTick会插队所以第二个输出, setTimeout设置延时为0毫秒, 也就是立即加入队列等待触发, 所以第三个输出, setImmediate需要等待前三个的 I/O 处理完毕后才会触发, 所以是最后一个.

另外, 如果 setTimeout 的延时时间比前面输出1和2的所消耗时间长的话, 就会使得 setImmediate 在 setTimeout 之前执行, 因为 setImmediate 得到了一个空闲期. 在我的机器上, 如果将延时设置为17ms, 将会随机出现1432和1423两种结果, 因为输出1和2的时间大致耗时17ms左右, 用时少于17ms就是1423, 多于就是1432

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值