JavaScript中setTimeout延迟设为0为何输出晚于后续同步代码
问题原因:JavaScript事件循环的任务调度规则
这个现象是JS单线程运行下的事件循环机制决定的,和你设置的0秒延迟没有直接关系:
核心逻辑
JavaScript是单线程语言,同一时间只能执行一个任务,所以运行时会把所有任务分成两类处理:
- 同步任务:直接进入主线程调用栈,按出现顺序排队执行,前一个没执行完不会处理下一个
- 异步任务:不会进入主线程直接排队,会先放到异步任务队列暂存,等主线程上所有同步任务全部执行完毕后,才会被主线程拉取执行
这段代码的实际执行流程
(function() { console.log(1); setTimeout(function(){console.log(2)}, 0); console.log(3); })();
- 首先运行立即执行函数,第一个
console.log(1)是同步任务,直接执行,输出1 - 遇到
setTimeout,就算你把延迟设为0,它依然属于异步宏任务,JS引擎会直接把它的回调函数扔到异步任务队列,不会阻塞后续同步代码的执行,继续往下走 - 碰到
console.log(3)是同步任务,直接执行,输出3 - 现在主线程上的所有同步任务已经全部跑完,才会去异步任务队列里取出
setTimeout的回调函数执行,最后输出2
补充说明:实际上就算没有事件循环的调度规则,浏览器对setTimeout也有默认的最小延迟限制(通常是4ms),你写的0延迟也不会真的立刻触发,所以无论怎么看2都会出现在3之后。
内容的提问来源于stack exchange,提问作者Nayereh Rasuli
相关产品推荐
相关产品推荐

