Promise - (五)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都有可能
相关文章
- 队列的两种实现方法
- C++优先队列_队列queue中添加元素的方法
- 分享如何把MongoDB作为循环队列的方法举例
- redis中队列消息实现应用解耦的方法
- IP address ‘121.41.35.30’ could not be resolved: Name or service not known解决方法详解数据库
- Linux系统中查看IP地址的简单方法(linuxip地址查看)
- Redis队列处理的方法介绍(redis如何做队列处理)
- 深入探究查询redis集合的方法(查询redis集合)
- 解决redis宕机的有效方法(如何处理redis宕机)
- 研究Redis队列的应用方法(redis队列怎么应用)
- Redis队列中实现去重的方法(redis 队列如何去重)
- 查看Redis队列大小的简单方法(redis队列大小查询)
- Redis队列出栈技术研究(redis队列出栈方法)
- jQuery动态显示和隐藏datagrid中的某一列的方法
- Array栈方法和队列方法的特点说明
- jquery队列queue与原生模仿其实现方法分享
- ASP.NET网站实时显示时间的方法
- python私有属性和方法实例分析
- C#判等对象是否相等的方法汇总