欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

随笔-then方法指定的回调函数加入异步微任务队列的时机

程序员文章站 2024-01-28 09:39:34
...

先看一个例子

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都有可能