随笔-then方法指定的回调函数加入异步微任务队列的时机
先看一个例子
Promise.resolve().then(()=>{
setTimeout(()=>{
console.log(1)
})
}).then(()=>{
console.log(2)
})
思考一个问题1
在JS事件循环机制触发前,即JS同步代码执行阶段,上面两个then都会执行吗?还是只执行第一个then?
答:两个then都会执行,因为then方法调用是同步的
再思考一个问题2
在JS事件循环机制触发前,即JS同步代码执行阶段,上面两个then都有返回值吗?是什么?
答:两个then执行后都会有返回值,且都是状态为pending的promise对象
再思考一个问题3
在JS事件循环机制触发前,即JS同步代码执行阶段,上面两个then执行结束后,对应的在执行栈中的函数执行上下文会被出栈销毁吗?
答:函数调用,则会创建函数执行上下文进入执行栈,函数调用结束,则对应的函数执行上下文出栈销毁。
终极一问4
then的执行上下文被销毁了,then指定的回调函数去哪了?也被销毁了吗?
答:then被销毁前,会对then指定的回调函数做一些处理:
若调用then的promise对象状态已经不是pending了,则直接将回调函数推入异步微任务队列中存储
若调用then的promise对象状态还是pending,则会将回调函数交给调用者promise对象缓存,当promise对象状态被异步修改后,再去将回调函数推入异步任务队列中存储。
补充一问5
在then方法调用前一刻,调用它的promise对象的状态是啥?一定是非pending吗,或一定是pending吗?
我们需要搞清楚,promise对象的状态会在哪里被修改
答:不考虑Promise内部实现,仅考虑Promise使用,则只有一个地方可以修改promise对象的状态,那就是new Promise(excutor)的excutor执行器函数中,在excutor函数中调用resolve或reject方法修改promise对象的状态。
promise对象状态的修改有几种情况?
两种,同步修改或异步修改
在excutor中同步调用resolve或reject会导致,then方法调用前一刻,promise对象的状态就已经是非pending了
在excutor中异步调用resolve或reject会导致,then方法调用结束后,promise对象的状态依旧是pending的
所以我们在重写then方法时,需要考虑promise对象的状态pending,非pending都有可能
上一篇: dense_flow复现
下一篇: AsyncTask异步任务