如何不修改延迟值,让长延迟setTimeout先于0延迟setTimeout执行?
解决方案:调整宏任务执行顺序
当然可以做到,核心思路是让输出d的逻辑等待输出c的逻辑执行完成后再触发,同时保留原有的延迟数值(2000和0)不变。
方法1:用Promise链式调用
把第一个setTimeout包装成Promise,在它的then方法里再触发输出d的setTimeout:
console.log('a') console.log("b") // 包装输出c的定时器为Promise const cPromise = new Promise(resolve => { setTimeout(() => { console.log('c') resolve() }, 2000); }) // 等待c输出后,再启动输出d的定时器 cPromise.then(() => { setTimeout(() => console.log('d'), 0); })
方法2:回调嵌套
直接把输出d的setTimeout放到输出c的定时器回调里:
console.log('a') console.log("b") setTimeout(() => { console.log('c') // 原延迟0的定时器,现在在c输出后执行 setTimeout(() => console.log('d'), 0); }, 2000);
原理说明
原代码的输出顺序是a b d c,因为两个setTimeout的回调都会进入宏任务队列:延迟0的回调会先被加入队列(当前同步代码执行完就触发),而延迟2000的回调要等2秒才加入队列,所以先执行d再执行c。
修改后,输出d的定时器是在c输出后才被创建的,它的回调会在c的回调执行完成后才进入宏任务队列,自然会在c之后执行,最终输出顺序就是a b c d。
内容的提问来源于stack exchange,提问作者Aniket Ingawale
相关产品推荐
相关产品推荐

