小白都能学会的的手写Promise(三)

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

前言

在之前的系列文章中已经实现Promise类核心逻辑以及Promise类中加入异步逻辑

小白都能学会的的手写Promise(一)

小白都能学会的的手写Promise(二)

本文的需求是实现then方法多次调用

核心内容

then方法的多次调用也存在同步和异步的两种执行状态

then方法的同步多次调用,与单次调用无差别,故只处理then方法中异步逻辑的代码

1.回顾上次已完成的代码

Snap.png

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文件如下

Snap (3).png

下面就可以用如下代码进行测试

当前只测试了异步成功的状态,其他的情况可以自主测试

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) 
})
复制代码

测试结果如下

image.png

总结

在本小节中,实现了then方法中多次调用的逻辑

多次调用虽然也分同步和异步的情况

但是多次调用时的同步状态下,与单次调用没有差别

都是直接调用成功或失败的回调函数,并将接收到的参数传递进去

而多次的异步调用则不同,所以只需要处理异步状态下的多次调用

处理步骤如下:

首先将成功回调和失败回调的初始值设置为数组

然后将then方法中异步逻辑进行处理,每次调用then方法都往对应的数组中添加一个函数

最后处理resolve()和reject( ) 方法,使得每次执行的时候,都执行对用的函数数组中的第一个函数

猜你喜欢

转载自juejin.im/post/7102733190866927624
今日推荐