Promise:手写Promise,原理分析
源码地址:https://gitee.com/lagou-19-web-paid/practice/tree/master/promise
1- Promise 对象的基础模型 (同步,分析执行流程)
- Promise 是一个类,类接收的是一个构造函数,在执行类的时候这个构造函数也会同步执行。
- 构造函数在同步执行的时候,会传递俩个回调函数,分别是成功回调[resolve]、失败回调[reject]。
- 成功回调:回调函数内接收一个参数,可以是一个普通值,也可以是一个 Promise 对象。此阶段暂时只考虑普通值。
- 失败回调:回调函数内接收一个参数,一般为失败原因
- Promise 中有三个状态,分别为 等待[pending]、成功[fulfilled]、失败[rejected]。状态仅支持 pending -> fulfilled 或 pending -> rejected,状态一旦确定就不支持修改了。
- then 方法会接收俩个参数,成功回调[successCallback]函数、失败回调[failCallback]函数。在 then 方法执行时,会依据Promise 的执行状态,执行成功回调或者失败回调。并在执行相对应的回调时,取出相对应的缓存状态值,作为参数传递至回调函数。
1 |
|
2- Promise 对象的异步特性
- 异步特点就是不会阻塞代码执行,待异步结束后才会得到特定的值、特定的函数才会执行。
- 当执行 Promise 中的 then 方法时,Promise 对象的状态为 pending[等待状态时],就断定为异步状态。
- 断定为异步状态时,successCallback[成功回调]、failCallback[失败回调] 需要缓存在 Promise 对象中。
- 在构造函数内的异步方法执行完毕,调用 resolve[成功回调] 、reject[失败回调] 时,前置逻辑处理完毕后,最后执行外部调用 then 方法挂载至 Promise 对象中的 successCallbak[成功回调] 或 failCallback[失败回调]。
1 |
|
3- Promise 支持多次调用的特性实现
- 创建 Promise 方法是可以被多次调用的,在调用后每个 then 方法都应该被正确执行。
- 改造缓存回调函数的容器为数组,每次执行 then 方法后,successCallback[成功回调]、failCallback[失败回调] 都应进入对应的缓存栈。
- 在构造函数内调用 resolve[成功回调] 、reject[失败回调] 时,循环执行缓存的回调函数,并在回调函数内传入当前 Promise 的成功数据,或失败原因。
1 |
|
4- Promise 链式调用的特性实现
- 链式调用过程中,then 方法的 successCallback[成功回调]、failCallback[失败回调],是可选项。如果为空,则直接返回上一个 Promise 对象的返回值。
- Promise 对象是支持链式调用的,在执行 then 方法的时候,最终会返回一个新的 Promise 对象。
- 返回的对象,不支持返回当前调用的 Promise 对象。
- 返回的对象如果是对象,则获取 promise 的返回值,依据返回值调用 resolve、reject。
- 返回值是普通值则,调用 resolve 方法。
1 |
|
5- Promise 中的 all、resolve、finally、catch 方法
Promise 中的 all 方法
- all 方法是一 Promise 的静态方法,可以直接调用。
- 接收的参数为数组,数组中可以有普通值、同步方法、异步方法。
- 调用 all 方法后,会依次按顺序执行形参中的数组包含的值或方法。每个值或执行方法后,获取到的结果应按形参中的顺序缓存。
- all 方法最终的返回值是一个 Promise 对象。如果形参中的每个方法都得以正确执行,没有异常则调用 Promise 对象中的 resolve 方法,把最终结果缓存至返回的 Promise 对象中。如果有异常则把异常的原因,则调用 Promise 对象中的 reject 方法,缓存失败原因。
- 执行 then 方法就可以获取到,all 顺利完整执行的结果,或某一个状态失败的原因。
Promise 中的 resolve 方法
- resolve 方法也是一个 Promise 的静态方法,可以直接调用。
- resolve 方法接收一个参数,这个参数可以是普通值,也可以是异步方法。
- 如果接收到的值是普通值,则包装为 Promise 方法后,返回这个 Promise 方法。
- 如果接收到的值是异步方法,则直接返回这个方法。
Promise 中的 finally 方法
- finally 方法在 Promise 对象执行后,无论结果是 fulfilled 或 rejected,都会被执行。
- finally 返回值应为一个 Promise 对象,并且继承当前 Promise 对象的状态。
- finally 对象由于无法知道 Promise 的状态,所以回调函数函数不接收任何参数,仅用于无论 Promise 对象何种状态,都要执行的情况。
Promise 中的 catch 方法
- catch 方法会捕获 Promise 的失败状态。
- catch 方法内部为调用 then 方法,第一个参数,成功状态为空。
6- 完整的 Promise 对象
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!