为什么setTimeout(fn, 0)不是立即执行?
我在写一个表单验证的时候,想让某个提示信息在当前同步代码执行完后立刻显示,就用了setTimeout(() => { showTip() }, 0),但发现它居然比 Promise.then 还慢?这不符合我对“0毫秒延迟”的理解啊。
我试过把 delay 改成 1、10,甚至直接不写,结果都一样——总是在微任务之后才执行。难道 setTimeout 即使设成 0 也不会插队到当前任务中间?
下面是我测试的代码:
console.log('start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
Promise.resolve().then(() => {
console.log('promise then');
});
console.log('end');
控制台输出顺序是:start → end → promise then → setTimeout。这到底是为啥?事件循环里宏任务和微任务到底怎么排的?
我一般直接记住这个顺序:同步代码 > 微任务 > 宏任务。所以你的代码里promise then永远比setTimeout先跑。
要立刻执行但又不想用Promise?可以试试这个骚操作:
或者更懒就直接用Promise.resolve().then(),虽然有点丑但管用。