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

关于两条不同setTimeout语句的执行行为疑问

关于setTimeout执行顺序的疑惑解答

嘿,这个问题其实是很多刚接触JS异步编程的开发者都会踩的坑,我来给你掰扯清楚~

核心原因:浏览器弹窗会阻塞JS执行线程

你的代码本身逻辑没问题,但**alert()弹窗会直接阻塞浏览器的JS执行线程**,这才是导致你看到“第二个弹窗立即弹出”的关键:

  1. 当页面加载后,两个setTimeout会被同时注册,它们的计时器会独立开始计时——第一个倒计时3秒,第二个倒计时5秒。
  2. 3秒后,第一个setTimeout的回调函数被加入到事件队列,JS线程空闲时执行它,弹出alert('hi')。
  3. 从这一刻开始,直到你手动关闭这个弹窗,浏览器的JS执行线程会被完全暂停,但浏览器的计时器并没有停!也就是说,在你盯着hi弹窗的这段时间里,第二个setTimeout的5秒倒计时早就走完了,它的回调已经在事件队列里等着了。
  4. 当你关闭第一个弹窗,JS线程恢复工作,发现事件队列里已经有第二个setTimeout的回调,就会立刻执行它,弹出hello。

如果不信的话,你可以把代码改成这样试试:

setTimeout(()=> console.log('hi'), 3000);
setTimeout(()=> console.log('hello'), 5000);

你会看到控制台确实是先在3秒后打印hi,再过2秒打印hello——因为console.log不会阻塞线程,事件队列能按正常的时间顺序处理回调。

深入学习的方向

要彻底搞懂这个问题,你需要吃透JS的事件循环(Event Loop)和宏任务/微任务机制,推荐你重点看这些内容:

  • MDN上关于「事件循环」的官方文档,它会详细解释浏览器如何处理异步任务的排队和执行顺序
  • 讲解JavaScript异步编程核心原理的文章,比如《深入理解JavaScript事件循环》这类内容,帮你理清计时器、事件队列和线程阻塞之间的关系

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 10:12:27