Node.js中setTimeout执行顺序疑问:为何输出D->C而非C->D?
为什么代码输出是
D -> C 而不是 C -> D? 先看运行的代码:
setTimeout(() => console.log('C'), 100); setTimeout(() => console.log('D'), 0); const t1 = new Date(); while (new Date() - t1 < 500) {/* block for 500ms */}
核心原因在于浏览器事件循环中setTimeout的工作逻辑:
setTimeout不是“到点就执行回调”,而是延迟指定时间后,把回调函数加入宏任务队列,只有等主线程空闲时,才会按队列顺序执行任务。- 代码执行时,两个
setTimeout被依次调用,但它们的回调入队时间不一样:- 第一个
setTimeout(C, 100):浏览器会在100ms后,把C的回调加入宏任务队列。 - 第二个
setTimeout(D, 0):虽然写的是0ms,但浏览器有最小延迟限制(一般是4ms),不过这里主线程直接阻塞了500ms,所以D的回调会在极短时间(远早于100ms)就被加入队列。
- 第一个
- 主线程被while循环卡了500ms,这段时间里D的回调早就进了队列,等100ms到点后C的回调才跟进队列。
- 宏任务队列的执行顺序是按回调入队的先后排序,D的回调比C早进队列,所以主线程空闲后会先执行D,再执行C。
你之前误以为是按setTimeout的调用顺序入队,但实际上入队时机由延迟到期时间决定,D的延迟先到期,自然先入队先执行。
内容的提问来源于stack exchange,提问作者lynxx
相关产品推荐
相关产品推荐

