You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

setInterval在Event loop中的行为疑问:为何代码输出与预期不符?

为什么setInterval的回调只执行一次在End之后?

先看你的代码:

console.log("Start");

setInterval(function() {
    console.log("setInterval");
}, 5000);

let date = new Date();
while(new Date() - date <= 10000) {}

console.log("End");

核心原因:浏览器对setInterval的任务队列去重机制

JavaScript的事件循环里,定时器的回调会在到期时被推入任务队列,但如果同一个setInterval的回调已经在任务队列里等待执行,浏览器不会重复添加这个回调,防止任务队列被大量重复的定时器回调塞满。

一步步拆解执行流程:

  1. 首先同步执行console.log("Start"),输出Start。
  2. 调用setInterval,浏览器注册一个间隔为5秒的定时器,记录下回调函数。
  3. 进入while循环,主线程被完全阻塞10秒,期间无法处理任何任务队列里的回调:
    • 第5秒时,定时器第一次到期,浏览器检查任务队列,发现没有该setInterval的回调等待,于是把回调推入任务队列。
    • 第10秒时,定时器第二次到期,浏览器检查任务队列,发现之前推入的回调还在队列里(因为主线程还在while循环,没机会执行),所以不会再推入第二个相同的回调。
  4. while循环结束,同步执行console.log("End"),输出End。
  5. 主线程现在空闲,开始处理任务队列里的回调,执行那个等待的setInterval回调,输出setInterval。
  6. 这次回调执行完成后,浏览器会重新计算下一次定时器的触发时间(从这次回调结束的时间开始算5秒),所以5秒后会再次触发回调,输出setInterval。

这就是为什么实际输出里,End之后只会先出现一次setInterval,而不是你预期的两次。

内容的提问来源于stack exchange,提问作者Avnish Ranwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 01:22:09