本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
大家好,我是除了开发,什么都想试试的布布。目前Promise 是 JavaScript 异步编程的一种流行解决方案,那理解promise原理早该提上日程了。理解原理?除了原生手写一个promise库,还能有什么更好的解决办法吗?
Promise 类
Promise 的构造函数必须接收一个函数参数(也就是需要执行异步任务的函数),该函数将在传入以后立即调用,并传入 Promise 对象下的两个方法 resolve 和 reject
Promise 状态
-
每一个 Promise 对象都存在以下三种状态:
- PENDING : 进行中,
Promise对象的初始状态 - FULFILLED : 已成功
- REJECTED : 已失败
- PENDING : 进行中,
每一个
Promise对象只能由PENDING状态变成FULFILLED或REJECTED,且状态发生变化以后就不能再改变了
一个 Promise 对象状态的变化并不由 Promise 对象本身来决定,而应该是由我们传入的异步任务完成情况来决定的,Promise 提供了两个用来改变状态的方法
promise.#resolve 方法
将 Promise 对象的状态从 PENDING 变为 FULFILLED,并执行成功后的注册任务
注意:如果当前状态已经改变过了,则直接
return
promise.#reject 方法
将 Promise 对象的状态从 PENDING 变为 REJECTED,并执行失败后的注册任务
注意:如果当前状态已经改变过了,则直接
return
实现promise
注意:由于篇幅有限,以下实现promise未写原代码比对。
实现promise的三种状态
实现then的问题
- 多个then(注意用数组保存且执行,避免只返回最后一个值,出现覆盖问题);
- 链式操作;
- then的返还值处理;
- 微任务宏任务问题
上面代码的结果受执行顺序的影响
为什么会出现上面的情况呢?这其实跟同步异步,微任务宏任务有必然的联系。我们对上面自己封装的promise进行一下异步操作,即将promise的两个方法最后run函数调用换成setTimeout(run) 异步调用即可。改完后顺序问题解决了,但又出现了其他问题。
先想一下下面代码按照自己封装的promise运行的结果:
但是按照原promise进行运行后,同样的代码得出的结果如下图:
对比之后发现,对于同步执行的代码,结果是相同的,但对于异步执行的代码,返回结果的顺序是不同的。这就反映出宏任务微任务的问题。
- 异步任务:
- 微任务:一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务执行之前。
- 宏任务:宏任务的时间颗粒比较大,执行的时间间隔是不能精确控制的,对一些高实时性的需求就不太符合。
- .then方法是一个微任务
想要解决宏任务微任务的问题就要用到MutationObserver构造函数进行监听操作,将then方法改成微任务。后续有时间在写一片关于MutationObserver讲解的文章吧。
实现then的链式调用及返回值问题。改造then方法:
周边方法
- 原型方法 catch 、finally
- 静态方法 race all allSettled resolve reject 写不完了,休息、休息一下。周边方法请看下一期!!!