事件循环题是JS面试出现频率最高的。答错等于告诉面试官你没调过异步代码。
两个队列:宏任务(setTimeout/setInterval/IO/UI事件)和微任务(Promise.then/queueMicrotask/MutationObserver)。
一轮:取一个宏任务→跑完→把所有微任务清空→必要时渲染→下一个宏任务。
关键点:每个宏任务跑完之后,所有待定微任务都会先跑,才到下一个宏任务或渲染。
Promise链会往微任务队列塞。await暂停函数,恢复点以微任务回来。
Node.js还多几个阶段(timers/I/O callbacks/poll/check/close)和process.nextTick(优先级比微任务还高)。
每轮:一个宏任务跑完,然后整个微任务队列清空,然后(浏览器里)可能渲染。经典题:`console.log(1); setTimeout(()=>console.log(2)); Promise.resolve().then(()=>console.log(3)); console.log(4)` 输出1、4、3、2——整段脚本是一个宏任务,同步先跑,然后微任务(3)清空,再下一个宏任务(setTimeout里的2)。常见坑:函数里的`await x`会把后面代码变成微任务,即使x已resolve,await后面的代码也是在调用方同步代码跑完之后才跑。心智模型:宏任务=粗粒度任务边界,微任务=细粒度的"收尾动作"。
queueMicrotask(fn)直接API——需要微任务顺序又不想造Promise时用。
微任务无限递归会饿死渲染——页面卡住。setTimeout(fn,0)能让出一帧。
即答侠把这些题做成限时测验——面试版就是肌肉记忆。
它在渲染阶段执行,微任务之后、下一个宏任务之前。面试场合单独归一类。
Node有明确阶段+process.nextTick(早于微任务)。浏览器是统一循环,渲染穿插其中。