Skip to content
静心静心
HOME
DoubtfulCases
github icon
  • TYPESCRIPT

    • 练习TS泛型简单的案例
      • vue3中div报错解决方案
        • typeof有何局限性如何解决
          • instanceof详解
            • 简简单单Promise

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

            author iconYYtimer icon大约 5 分钟

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

            简易TS版手写open in new window

            # 第一步简单定义一下基本属性,准备一个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("失败")
            })
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37

            # 第二步. 实现then方法

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

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

            
            
            class newPromise<T = any> {
                // ....
                 then(resolve: resolveType, reject: resolveType) {
                     let result: any // 定义一个变量result 来接收值
                     if(this.status === 'success'){  // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
                         ....
                     }
                     if(this.status === 'fail'){  // 这个地方只要是为了有先后顺序, 只要实例化对象那里,根据上面的状态改变,来执行
                         ....
                     }
                 }
            }
            
            
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16

            # 第二步. 实现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)
                     }
                    }
                  
                 }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26

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

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

            type callFunction = () => any
            
            class 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)
                            })
                        }
                    }
                  
                 }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44

            # 第三步(附加). 上述情况们只讨论了返回一个值的情况,如果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"
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            
            		// ...
            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)
                    }
                }
                                          } 
             /....
            
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22

            # 第四步,实现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)
                            }
                        }
                    })
                }
            
            
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28

            # 完整代码

            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"
            }
            
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            71
            72
            73
            74
            75
            76
            77
            78
            79
            80
            81
            82
            83
            84
            85
            86
            87
            88
            89
            90
            91
            92
            93
            94
            95
            96
            97
            98
            99
            100
            101
            102
            103
            104
            105
            106
            107
            108
            109
            110
            111
            112
            113
            114
            edit icon编辑此页open in new window
            上一页
            instanceof详解
            傻瓜都能写出计算机可以理解的代码。唯有能写出人类容易理解的代码的,才是优秀的程序员。
            Copyright © 2022 YY

            该应用可以安装在您的 PC 或移动设备上。这将使该 Web 应用程序外观和行为与其他应用程序相同。它将在出现在应用程序列表中,并可以固定到主屏幕,开始菜单或任务栏。此 Web 应用程序还将能够与其他应用程序和您的操作系统安全地进行交互。

            详情