首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

首先发生什么: setTimeout 0还是等待Promise.resolve?

在JavaScript中,setTimeoutPromise.resolve的执行顺序涉及到事件循环(Event Loop)的机制。为了更好地理解这个问题,我们需要先了解一些基础概念。

基础概念

  1. 事件循环(Event Loop)
    • JavaScript是单线程的,但它通过事件循环机制来处理异步操作。
    • 事件循环负责处理任务队列(Task Queue)和微任务队列(Microtask Queue)中的任务。
  • 宏任务(MacroTask)和微任务(MicroTask)
    • 宏任务包括:setTimeoutsetIntervalI/O、UI渲染等。
    • 微任务包括:Promise.thenprocess.nextTick(Node.js)、MutationObserver等。

执行顺序

根据事件循环的机制,微任务会在当前宏任务执行完毕后立即执行,而宏任务则会在下一个事件循环周期开始时执行。

示例代码

代码语言:txt
复制
console.log('Script start');

setTimeout(() => {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(() => {
  console.log('Promise.resolve');
});

console.log('Script end');

输出顺序

  1. Script start
  2. Script end
  3. Promise.resolve
  4. setTimeout

解释

  1. Script startScript end
    • 这两个日志会在脚本开始执行时立即输出。
  • Promise.resolve
    • Promise.resolve会立即执行,并将其回调函数放入微任务队列。
    • 当前宏任务(脚本执行)完成后,事件循环会立即处理微任务队列中的任务,因此Promise.resolve的回调函数会在Script end之后立即执行。
  • setTimeout
    • setTimeout会将回调函数放入宏任务队列,但不会立即执行。
    • 当前宏任务和所有微任务处理完毕后,事件循环才会处理宏任务队列中的任务,因此setTimeout的回调函数会在所有微任务之后执行。

结论

在JavaScript中,Promise.resolve的回调函数会在当前宏任务完成后立即执行,而setTimeout的回调函数会在下一个事件循环周期开始时执行。因此,Promise.resolve会先于setTimeout执行。

参考链接

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Promise面试题,一次爽到底

,但其状态还是为pending,这里理解为先不执行 执行同步代码4 一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它 首先执行timerStart,然后遇到了resolve...0) }, 0) setTimeout(() => { console.log('timer2') }, 0) console.log('start') 复制代码 (2) setTimeout((...) => { console.log('timer1'); Promise.resolve().then(() => { console.log('promise') }) }, 0...console.log('timer2') }, 0) }); const timer1 = setTimeout(() => { console.log('timer1') Promise.resolve...1 遇到定时器timer1,将它加入下一次宏任务的延迟列表,标记为宏2,等待执行(先不管里面是什么内容) 执行宏1中的同步代码start 第一次宏任务(宏1)执行完毕,检查第一次的微任务队列(微1),发现有一个

73510
  • 你真的懂Promise吗

    new Promise出来的实例,成功或者失败,取决于executor函数执行的时候,执行的是resolve还是reject决定的,或executor函数执行发生异常错误,这两种情况都会把实例状态改为失败的...接下来,我们一步一步分析: 首先执行同步代码,输出 1,遇见第一个setTimeout,将其回调放入任务队列(宏任务)当中,继续往下执行 运行run(),打印出 5,并往下执行,遇见 await fn(...),将其放入任务队列(微任务) await fn() 当前这一行代码执行时,fn函数会立即执行的,打印出3,遇见第二个setTimeout,将其回调放入任务队列(宏任务),await fn() 下面的代码需要等待返回...值得注意的是,这个定时器 推迟时间0毫秒实际上达不到的。根据HTML5标准,setTimeOut推迟执行的时间,最少是4毫秒。...executor函数执行,打印出8,然后在执行resolve时,触发微任务,于是打印出9 最后执行第一个setTimeout的宏任务,打印出2 常用的方法 1、Promise.resolve() Promise.resolve

    97021

    惊艳!可视化的 js:动态图演示 Promises & AsyncAwait 的过程!

    让我们为脚本添加一些更多的代码并且再次运行它: 等下,发生什么?! 首先,Start! 被输出。 好的,我们已经看到了那一个即将到来的消息:console.log('Start!')...尽管我们为计时器提供的值是 0,在它被添加到宏任务队列 (setTimeout 是一个宏任务) 之后回调还是会被首先推入 Web API。...到了去检查宏任务队列的时候了:setTimeout 回调仍然在那里等待setTimeout 被弹入调用栈。回调函数返回 console.log 方法,输出了字符串 In timeout!。...很好,但这到底是什么意思? 当我们运行下面的代码块时让我们看下发生什么: 额,这里发生什么呢? 首先,JavaScript 引擎遇到了 console.log。...最先发生的事是被等待的值执行:在这个例子中是函数one。它被弹入调用栈,并且最终返回一个解决状态的promise。

    2.1K10

    来45道Promise面试题一次爽到底(1.1w字用心整理)

    ,但其状态还是为pending,这里理解为先不执行 执行同步代码4 一轮循环过后,进入第二次宏任务,发现延迟队列中有setTimeout定时器,执行它 首先执行timerStart,然后遇到了resolve..., 0) }, 0) setTimeout(() => { console.log('timer2') }, 0) console.log('start') (2): setTimeout(()...console.log('timer2') }, 0) }); const timer1 = setTimeout(() => { console.log('timer1') Promise.resolve...遇到定时器timer1,将它加入下一次宏任务的延迟列表,标记为宏2,等待执行(先不管里面是什么内容) 执行宏1中的同步代码start 第一次宏任务(宏1)执行完毕,检查第一次的微任务队列(微1),发现有一个...这么多的1,2,3脾气就上来了,不是说好了本篇文章没什么屁话嘛,怎么还是这么多一二三四。 ?,你要理解我的用心良苦啊,我这是帮你把知识点都列举出来,做个总结而已。

    1.9K20

    Promise 源码分析

    promise规范规定必须要异步的,浏览器实现的promise应该用的是浏览器内部的一些特性(不知道具体是什么),,,但是外部 promise 在 js 层面代码层面上怎么实现异步的呢,答案是:setTimeout...但是为什么可以把回调函数放到未来去注册?             理由是:异步(setTimeout异步或者浏览器自己的实现),确保了then()函数肯定在链条启动前就执行了!...▲ then链条如何保证顺序 test2.png 1、promise1对象有了,显然是执行到setTimeout等待步骤了,状态是pending,timeout完成,立马就是fullfill状态并执行fullfill...我们知道,在你的resovler代码里需要调用resovle函数才能使promise进入到setTimeout等待中。...5、也就是,只有promise1状态完成时,新的promise2才能进入setTimeout等待。 6、依次类推,,一环扣一环,,保证了链条有序执行。

    1.8K50

    js异步编程面试题

    回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装,参考 前端进阶面试题详细解答Promise.resolve(1) .then(res...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?

    58930

    js异步编程面试题你能答上来几道_2023-05-19

    回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装,参考 前端进阶面试题详细解答Promise.resolve(1) .then(res...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?

    33220

    js异步编程面试题你能答上来几道

    回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装Promise.resolve(1) .then(res => { console.log...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?

    51820

    js异步编程面试题你能答上来几道

    回调函数(callback)面试题: 什么是回调函数?回调函数有什么缺点?如何解决回调地狱问题?...如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装Promise.resolve(1) .then(res => { console.log...b先执行,在执行await 10之前变量a还是0,因为await内部实现了generator,generator会保留堆栈中东西,所以这个时候a = 0被保存下来因为await是异步操作,后来的表达式不返回...promise的话,就会包装成Promise.resolve(返回值),然后去执行函数外的同步代码同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10上述解释中提到了...常用定时器面试题: setTimeout,setInterval,requestAnimationFrame 各有什么特点?

    48600

    JS 异步

    如果同步代码执行完,调用栈call stack为空,去查看微任务队列,每执行完一个微任务,它就会从微任务队列出队,直到微任务队列微空后,尝试DOM渲染(如果DOM结构发生变化)。...宏任务:DOM渲染后触发,如setTimeout 微任务:DOM渲染前触发,如Promise 为什么微任务在渲染前,宏任务在渲染后? - 微任务:ES 语法标准之内,JS 引擎来统一处理。...console.log('promise3') }) }, 200) 先将两个setTimeout塞到宏任务队列中 当第一个setTimeout1时间到了执行的时候,首先打印timeout1...(function (){ console.log('setTimeout'); }, 0) async1(); new Promise(function (resolve) {...为什么这里有返回undefined之后才会打印setTimeout,因为前面是同步代码和微任务执行完了,JS引擎工作结束,开始返回值。后面打印的setTimeout是浏览器处理的。

    3.4K20
    领券