持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
前情提要
在上篇文章研究js的事件循环(Event Loop)的时候发现了一个问题。我在代码的一级列里同时写了setTimeout和setImmediate。其中setTimeout的延迟时间设置为了0。然后第一次运行setTimeout先执行,setImmediate后执行。但是当我继续重复几次之后,发现他们俩居然会偶尔的相互交替先执行。一会setTimeout先执行,一会setImmediate先执行。好奇怪呀。
展示
示例一
-
代码
setTimeout(() => { console.log(1) }, 0) setImmediate(() => { console.log(2) }) -
执行结果
-
总结:从多次执行结果上看,他们俩确实会出现一会他前一会他后的问题。
-
原因: ?
示例二
-
代码
function fn() { setTimeout(() => { console.log(1); }, 0); setImmediate(() => { console.log(2); }); } fn(); -
执行结果
-
总结:从代码执行结果上来看,大多数情况下在方法里是setImmediate先执行,setTimeout延迟为0后执行。但偶尔也会反过来。
-
原因:?
浏览器环境
我将上述的代码又放到了浏览器里去执行。执行了很多次之后发现打印结果始终都是先打印2后打印1。上述代码是在node环境中执行的。也就是说这种不稳定的情况只出现在node环境中,在浏览器环境中并不存在。这个结论可以让我们放心大胆的去写前端涉及这两个逻辑了。
打破砂锅问到底:为什么node环境会出现这个问题?
- 在查阅了很多资料后发现问题可能出现在了node的事件循环上。
- 事实上浏览器的事件循环与node的事件循环并不一样。也因此产生了如此的差异
- 具体原因是在node找那个基本上做不到0秒,其处理逻辑最少也需要1毫秒的时间。此时进入事件循环后,如果没有到1毫秒,那么就会跳过,进而执行下面的。如果到了就会执行上面的。所以出现了不稳定的情况。
- 上一句的解释可能会差强人意些,有兴趣的xdm可以着重的了解下node的事件循环。待我有时间了解清楚node事件循环后再来详细解释。