持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
前言
在之前的系列文章中已经实现Promise类核心逻辑以及Promise类中加入异步逻辑
本文的需求是实现then方法多次调用
核心内容
then方法的多次调用也存在同步和异步的两种执行状态
then方法的同步多次调用,与单次调用无差别,故只处理then方法中异步逻辑的代码
1.回顾上次已完成的代码
2.改变成功回调和失败回调的初始值
把初始值改为空数组
因为只有数组才能储存多个回调函数
//successCallback = undefined;
successCallback = [];
//failCallback = undefined;;
failCallback = [];
复制代码
3.处理then方法
将then方法中等待情况(也就是异步逻辑代码)下的代码进行处理
由原来的直接赋值,变为push到数组中
这样的话,每次执行then方法时,就能把失败函数或者成功函数储存到对应的数组中
//then方法是被定义在原型对象中的
then (successCallback, failCallback) {
// 判断状态
if (this.status === FULFILLED) {
...
}else if(this.status === REJECTED){
...
}else {
//旧
//this.successCallback=successCallback
//this.failCallback=failCallback
//新
this.successCallback.push(successCallback);
this.failCallback.push(failCallback);
}
}
复制代码
4.改造resolve()和reject()
在执行then方法都已经存放在数组中,当执行成功或失败时,从前往后依次调用数组中的函数即可
- 将数组的长度作为循环条件,每次执行的时候使用shift()弹出当前首个函数
- 将弹出的函数直接执行,并传入接收到的值作为参数
- 当数组中没有函数时,就会停止执行
改造resolve()
resolve = value => {
...
// 判断成功回调是否存在 如果存在 调用
//this.successCallback && this.successCallback(this.value);
while(this.successCallback.length) this.successCallback.shift()(this.value)
}
复制代码
改造reject()
reject = reason => {
...
// this.failCallback && this.failCallback(this.reason);
while(this.failCallback.length) this.failCallback.shift()(this.reason)
}
复制代码
那么,完成后的myPromise.js文件如下
下面就可以用如下代码进行测试
当前只测试了异步成功的状态,其他的情况可以自主测试
const Mypromise = require('./myPromise');
let promise =new Mypromise((resolve,reject) => {
// resolve('成功')
// reject('失败')
setTimeout(()=>{
resolve('成功...')
},2000)
})
promise.then(value => {
console.log(value);
},(reason) => {
console.log(reason)
})
promise.then(value => {
console.log(value);
},(reason) => {
console.log(reason)
})
复制代码
测试结果如下
总结
在本小节中,实现了then方法中多次调用的逻辑
多次调用虽然也分同步和异步的情况
但是多次调用时的同步状态下,与单次调用没有差别
都是直接调用成功或失败的回调函数,并将接收到的参数传递进去
而多次的异步调用则不同,所以只需要处理异步状态下的多次调用
处理步骤如下:
首先将成功回调和失败回调的初始值设置为数组
然后将then方法中异步逻辑进行处理,每次调用then方法都往对应的数组中添加一个函数
最后处理resolve()和reject( ) 方法,使得每次执行的时候,都执行对用的函数数组中的第一个函数