promise then 的回调函数是在什么时候进入微任务队列的?
promise then 的回调函数是在遇到 resolve 语句的时候就被加入微任务队列,还是在遇到 then 语句的时候被加入到微任务队列?
在网上查了一些资料,发现有不同的说法:
- 比如在《深入理解ES6》中文版 244 页里是这么说的:“调用 resolve( ) 后会触发一个异步操作, 传入 then( ) 和 catch( ) 方法的函数会被添加到任务队列中并异步执行”,所以 then 方法的回调应该是在调用 resolve 后就被加入到队列中的?
- 对应的英文版原文是这么说的:“Calling resolve() triggers an asynchronous operation. Functions passed to then() and catch() are executed asynchronously, because these are also added to the job queue”
- 这个是知乎的回答:链接
- 这个是 StackOverflow 类似问题的回答:链接 ,答主在分析 event loop 的时候有这么一句:“The first then hooks up the first fulfillment handler, queuing a PromiseJobs job because the promise is already fulfilled”
1、2 都认为 then 的回调函数是在遇到 resolve 语句的时候就被加入微任务队列,3、4 都认为是在遇到 then 语句的时候被加入到微任务队列的。到底哪一种说法是正确的呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
都没问题。
关键在于,
then
是在resolve
之前被调用的,还是resolve
之后呢?then
在resolve
之前,then
不会加微任务,而是缓存起来,resolve
看到缓存里又then
的回调,于是加微任务。resolve
在then
之前,resolve
的时候还没有任何回调要执行,自然不会加微任务。then
的时候发现已经 fullfilled ,于是直接加微任务。也就是说,他们都有可能加,也都有可能不加,就看调用时的 promise 的状态了。
你的引用有些只说明了其一,但是说明里条件写得还是很清楚的,比如 4 里 "because the promise is already fulfilled"
发表下我的意见,在我的理解里,Promise 的实现中,then 只会把回调放到一个数组里保存,所以我认为,reslove 后,才会进入微任务队列,存放callback 只是一个存放的操作
当然 如果then的运行还没执行的时候,promise 已经reslove 了 ,我觉得会是同步的去把callback放入 microtasks的。
总结起来就是 reslove -> then
执行一个宏任务,过程中遇到微任务时,将其放到微任务的事件队列里,当前宏任务执行完成后,会查看微任务的事件队列,依次执行里面的微任务。如果还有宏任务的话,再重新开启宏任务……
再结合一个例子看下:
1.首先执行
script
下的宏任务,遇到setTimeout
,将其放入宏任务的队列里。2.遇到
Promise
,new Promise
直接执行,打印b。3.遇到
then
方法,是微任务,将其放到微任务的队列里。4.遇到
console.log('d')
,直接打印。5.本轮宏任务执行完毕,查看微任务,发现
then
方法里的函数,打印c。6.本轮
event loop
全部完成。7.下一轮循环,先执行宏任务,发现宏任务队列中有一个
setTimeout
,打印a。发现老贺有答案了,比较喜欢这种讲事实摆依据的