SetInterval与Async Await结合的异常行为问题咨询
问题原因解析
核心差异:任务的同步/异步本质
JavaScript是单线程环境,所有任务都要通过事件循环排队执行,这是两个函数表现天差地别的根本原因。
1. Brutal_Workload的表现
虽然名字带“异步”,但它本质是同步的高耗时任务——用大量同步循环模拟耗时,执行时会完全霸占主线程,直到整个循环跑完才会释放资源。
当把它放进每秒30次的setInterval(约每33ms触发一次):
- 第一次
setInterval触发后,Brutal_Workload开始执行,主线程被阻塞1秒以上; - 这期间
setInterval的后续调度(每33ms一次)都会把任务放进宏任务队列,但主线程被同步任务占着,队列里的任务根本没机会执行; - 直到上一次Brutal_Workload执行完毕,队列里最早的等待任务才会启动,又再次阻塞主线程。
所以最终每秒只能输出1次BLIP。
2. Time_Wait的表现
它是真正的异步任务——基于setTimeout实现,调用它的时候,只有“发起setTimeout请求”这一步是同步执行的,瞬间就能完成,不会阻塞主线程。
当放进同间隔的setInterval:
- 每33ms
setInterval触发一次,调用Time_Wait,同步代码瞬间执行完毕,主线程立刻空闲; - 后续的
setInterval调度能按时触发,每次都能顺利调用Time_Wait并输出BLIP; - Time_Wait里的
setTimeout回调会在1秒后进入宏任务队列,但这是独立的任务,完全不影响setInterval的调度节奏。
所以每秒能输出30次BLIP,和setInterval的设定一致。
补充:Time_Wait在setInterval外正常工作的原因
单独调用时,Time_Wait里的setTimeout会正常等待1秒后执行回调,这是因为没有其他高频调度任务抢占主线程,异步回调能按时执行。但在setInterval里,它只是“发起异步等待”,本身不占用主线程,所以不影响setInterval的触发频率。
内容的提问来源于stack exchange,提问作者resle
相关产品推荐
相关产品推荐

