简易TS版手写Promise

123 阅读4分钟

简易TS版手写Promise通俗易懂,简单的爆

简易TS版手写

第一步简单定义一下基本属性,准备一个promise的类,结合现有的promise

定义其属性

当前状态 status

一个成功的回调函数resolve

一个失败的函数 reject

一个外面的传入值 rejectResolveValue

// 声明部分
type resolveType = (value: string) => void
type rejectType = (value: string) => void// 根据promise 用法, 会回调两个函数
type Excuted = (resolve: resolveType, reject: rejectType) => void// 实现部分
class newPromise<T = any> {
    public reject !: rejectType
    public resolve!: resolveType
    public status!: 'pending' | 'success' | 'fail'; // 这里固定pending success fail 3种
    public rejectResolveValue!: any; // 的值
    constructor(exce: Excuted) {   
        this.status = 'pending'
        this.reject = (val: any) => {
            this.status = 'fail'
            this.rejectResolveValue = val;
        }
        this.resolve = (val: any) => {
            this.status = 'success'
            this.rejectResolveValue = val;
        }
        try {
            exce(this.resolve, this.reject)
        } catch (error) {
            this.reject(error as any)
        }
    }
}
​
// 测试部分let myPro = new newPromise((resolve, reject) => {
       // resolve("初始化数据")
    reject("失败")
})

第二步. 实现then方法

类里面加一个then()的方法,传入两个方法,

判断状态是否改变,选择执行,成功还是失败

​
​
class newPromise<T = any> {
    // ....
     then(resolve: resolveType, reject: resolveType) {
         let result: any // 定义一个变量result 来接收值
         if(this.status === 'success'){  // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
             ....
         }
         if(this.status === 'fail'){  // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
             ....
         }
     }
}
​
​

第二步. 实现then方法的连续调用

我们通过返回一个newPromise对象重复上面的工作

class newPromise<T = any> {
    // ....
     then(resolve: resolveType, reject: resolveType) {
         
       return new newPromise((resolve2, reject2) => {
           // 定义一个变量result 来接收值
         let result: any 
           // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
         if(this.status === 'success'){ 
             // 回炉重造
             result = resolve(this.rejectResolveValue) 
             // 返回成功值
             resolve2(result) 
         }
            // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
         if(this.status === 'fail'){ 
              // 回炉重造
             result = resolve(this.rejectResolveValue)
             // 返回失败值
             reject(result)
         }
        }
      
     }
}

第三步. 开始处理异步操作, 如果一直为pending怎么半

我们在类里面多加一个属性来存储我们将要执行的方法.等到我的异步事件执行完后,我们再依次执行

type callFunction = () => anyclass newPromise<T = any> {
    
    // 用来存储成功或失败函数
    public resolveCallList: callFunction[] = [];
    public rejectCallList: callFunction[] = [];
    // ....
     then(resolve: resolveType, reject: resolveType) {
         
       return new newPromise((resolve2, reject2) => {
           // 定义一个变量result 来接收值
         let result: any 
           // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
         if(this.status === 'success'){ 
             // 回炉重造
             result = resolve(this.rejectResolveValue) 
             // 返回成功值
             resolve2(result) 
         }
            // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
         if(this.status === 'fail'){ 
              // 回炉重造
             result = resolve(this.rejectResolveValue)
             // 返回失败值
             reject(result)
         }
           
         if (this.status === "pending") {  // 这里开始处理异步事件
​
                this.resolveCallList.push(() => {
                     let result: any = resolve(this.rejectResolveValue)
                     resolve2(result)
            
                })
​
                this.rejectCallList.push(() => {
                    reject2(reject(this.rejectResolveValue) as any)
                })
            }
        }
      
     }
}

第三步(附加). 上述情况们只讨论了返回一个值的情况,如果then函数里面返回了一个Promise怎么办?

判断一下是否是newPromise对象即可,然后回炉重造

// 这个地方来判断是否是穿进来的promise 对象
function isPromise(val: any): val is newPromise {
​
    return isObject(val) && isFunction(val.then)
}
​
function isObject(val: any): val is Record<any, any> {
    return val !== null && typeof val === 'object'
}
​
function isFunction(val: any): val is Function {
    return typeof val === "function"
}
// ...
if (this.status === "pending") {
​
    this.resolveCallList.push(() => {
        let result: any = resolve(this.rejectResolveValue)
​
        if (isPromise(result)) {
            result.then(
                (val) => {
                    resolve2(val)
                },
                (val) => {
                    reject2(val)
                })
        } else {
            resolve2(result)
        }
    }
                              } 
 /....
​

第四步,实现promise.all()的用法

传入多个promise对象, 我们吧每个promise异步或同步操作的值全部返回到一个列表中,然后通过then方法获取到值

all()实现方法:

定义一个静态方法

接收多个promise ,

返回一个promise 回炉重造即可

static all(Promises: newPromise[]): newPromise {  // 输入多个promise ,返回一个
​
        return new newPromise((resolve, reject) => {
            // 定义一个列表用来保存每个处理结果后值
            let resRejDatalist: any[] = [];
            Promises.forEach((promise, index) => {  // 这里循环调用每个promise
                promise.then(
                    res => {
                        console.log(res);
                        processPromiseData(res, index)
                    },
                    rej => {
                        reject(rej);
                        return
​
                    }
                )
            })
            function processPromiseData(val: any, index: number) {  // 如果每个promise都处理放在我们就返回数据
                resRejDatalist[index] = val;
                if (Promises.length - 1 === index) {
                    resolve(resRejDatalist as any)
                }
            }
        })
    }
​
​

完整代码

type callFunction = () => any
type resolveType = (value: string) => void
type rejectType = (value: string) => void
type Excuted = (resolve: resolveType, reject: rejectType) => void
class newPromise<T = any> {
    public reject !: rejectType
    public resolve!: resolveType
    public status!: 'success' | 'fail' | "pending"
    public rejectResolveValue!: any;
    public resolveCallList: callFunction[] = [];
    public rejectCallList: callFunction[] = [];
    constructor(exce: Excuted) {
        this.status = 'pending'
        this.reject = (val: any) => {
            this.status = 'fail'
            this.rejectResolveValue = val;
            this.rejectCallList.forEach(voild => voild())
        }
        this.resolve = (val: any) => {
            this.status = 'success'
            this.rejectResolveValue = val;
            this.resolveCallList.forEach(voild => voild())
        }
        try {
            exce(this.resolve, this.reject)
        } catch (error) {
            this.reject(error as any)
        }
    }
    then(resolve: resolveType, reject: resolveType) {
        return new newPromise((resolve2, reject2) => {
            let result: any;
            console.log(this.status, 'this.status');
            if (this.status === 'success') {
                result = resolve(this.rejectResolveValue)
                console.log(typeof result);
                console.log(typeof result.then);
                resolve2(result)
            }
​
            if (this.status === 'fail') {
                result = resolve(this.rejectResolveValue)
                reject(result)
​
            }
​
            if (this.status === "pending") {
​
                this.resolveCallList.push(() => {
                    let result: any = resolve(this.rejectResolveValue)
​
                    if (isPromise(result)) {
                        result.then(
                            (val) => {
                                resolve2(val)
                            },
                            (val) => {
                                reject2(val)
                            })
                    } else {
                        resolve2(result)
                    }
​
                })
                // 这里不想改了, 和成功一样要判断isPromise
                this.rejectCallList.push(() => {
                    reject2(reject(this.rejectResolveValue) as any)
                })
            }
        })
​
    }
    static all(Promises: newPromise[]): newPromise {
​
        return new newPromise((resolve, reject) => {
            // 定义一个列表用来保存每个处理结果后值
            let resRejDatalist: any[] = [];
            Promises.forEach((promise, index) => {
                promise.then(
                    res => {
                        console.log(res);
                        processPromiseData(res, index)
                    },
                    rej => {
                        reject(rej);
                        return
​
                    }
                )
            })
            function processPromiseData(val: any, index: number) {
                resRejDatalist[index] = val;
                if (Promises.length - 1 === index) {
                    resolve(resRejDatalist as any)
                }
            }
        })
    }
}
​
// 这个地方来判断是否是穿进来的promise 对象
function isPromise(val: any): val is newPromise {
​
    return isObject(val) && isFunction(val.then)
}
​
function isObject(val: any): val is Record<any, any> {
    return val !== null && typeof val === 'object'
}
​
function isFunction(val: any): val is Function {
    return typeof val === "function"
}
​

\