一次就想搞懂这个Promise

2022-10-25 14:06:26 浏览数 (2)

看了好多例子,调试了很久,结果和内置promise还是存在一点差异,不尽相同。

代码语言:javascript复制
// 重点是then的参数两个参数是函数,而这两个函数的返回值,可能是一个Promise对象,或一个普通对象或一个有then方法的对象或者是个基础数据类型


    class Promise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(excutor) {
            if (typeof excutor !== 'function') {
                throw new TypeError('类型不对')
            }
            this.state = Promise.PENDING //初始状态pending
            this.value = undefined //成功时值临时变量
            this.reason = undefined //被拒绝原因
            this.onFulfilledCallbacks = [] //成功后执行函数
            this.onRejectedCallbacks = [] //被拒绝后执行函数
            try {
                // 立即执行
                excutor(this.resolve, this.reject)
            } catch (error) {
                console.log(error)
            }
        }
        resolve = (value) => {
            // 状态不可逆
            if (this.state === Promise.PENDING) {
                this.state = Promise.FULFILLED
                this.value = value;
                // 执行then的第一个参数,把成功结果传入
                this.onFulfilledCallbacks.forEach(fn => fn(value))
            }
        }
        reject = (reason) => {
            if (this.state === Promise.PENDING) {
                // 状态为失败
                this.state = Promise.REJECTED
                this.reason = reason;
                // 被拒时执行then的第二个参数,把成功结果传入
                this.onRejectedCallbacks.forEach(fn => fn(reason))
            }
        }
        // 接受一个成功和一个失败函数
        then = (onFulfilled, onRejected) => {
            // 用户是爷爷,可能不传入onFulfilled或onRejected
            if (typeof onFulfilled !== 'function') {
                // 不是函数,就赋值一个啥也不干的函数
                onFulfilled = value => value;
            }
            if (typeof onRejected !== 'function') {
                // 失败参数不是函数,就赋值一个怎么做都是错的函数
                onRejected = reason => {
                    throw new TypeError(reason)
                }
            }
            // then方法链式调用,返回一个新的Promise对象,这个Promise对象是内部设置的,
            let promise2 = new Promise((resolve, reject) => {

                // 如果上面的Promise结果已经成功,也就是当用户传入的函数在同步代码中执行了resole()
                // 例如new Promise(resolve=>resolve('test'));这样,实际上promise已经是成功状态,只是在等then方法调用了
                if (this.state === Promise.FULFILLED) {
                    // 由于promise状态为成功,执行then的成 功回调
                    setTimeout(() => {
                        const x = onFulfilled(this.value);
                        // 所有这里要解析一下x,看看看是啥类型
                        this.resolvePromise(promise2, x, resolve, reject)
                    }, 0);
                }
                if (this.state === Promise.REJECTED) {
                    // 同理,失败了就执行失败回调
                    setTimeout(() => {
                        const x = onRejected(this.reason);
                        // 所有这里要解析一下x,看看看是啥类型
                        this.resolvePromise(promise2, x, resolve, reject)
                    }, 0);
                }
                if (this.state === Promise.PENDING) {
                    // 既没成功,又没失败。用创建promise的函数里面可能有个异步函数,在异步函数中resolve的,也可能用户根本 没想resolve()
                    // 发布订阅,将回调存好,他总会resolve的,不resolve我就不执行,resolve我就执行
                    this.onFulfilledCallbacks.push((value) => {
                        setTimeout(() => {
                            // then函数的第一个参数是成功函数,它的返回值可能是个promise,如果是promise就拿到他的resove值
                            const x = onFulfilled(this.value);
                            // 所有这里要解析一下x,看看看是啥类型
                            this.resolvePromise(promise2, x, resolve, reject)
                        }, 0)
                    })
                    this.onRejectedCallbacks.push((reason) => {
                        setTimeout(() => {
                            const x = onRejected(reason);
                            // 错误也不能大意
                            this.resolvePromise(promise2, x, resolve, reject)
                        }, 0)
                    })
                }
            })
            // 别忘了return 这孙子
            return promise2;

        }
        resolvePromise = (promise2, x, resolve, reject) => {
            // 怕他把then的返回 值扔回
            if (promise2 === x) {
                throw new TypeError('循环引用是干啥?')
            }
            // 保证只执行一次
            let called = false;
            //判断是否为Promise
            if (x instanceof Promise) {
                // x若是promise,就then它一下,它的reslove就是咱们要reslove的值
                x.then(value => {
                    // 不敢保证用户嵌套几层promise,检验一下没错
                    this.resolvePromise(promise2, value, resolve, reject)
                },
                    reason => {
                        reject(reason)
                    })
            } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
                // x不是普通值,对象或者方法
                try {
                    // x是对象,并且then属性是function
                    if (typeof x.then === 'function') {
                        const then = x.then;
                        then((value) => {
                            if (called) return
                            called = true;
                            // 继续递归
                            this.resolvePromise(promise2, value, resolve, reject)
                        }, reason => {
                            if (called) return
                            called = true;
                            reject(reason)
                        })
                    } else {
                        if (called) return
                        called = true
                        // 啥也不是就直接resolve吧
                        resolve(x)
                    }
                } catch (e) {
                    if (called) return
                    called = true
                    // 报错就reject
                    reject(e)
                }
            } else {
                if (called) return
                called = true
                // 啥也不是就直接resolve吧
                resolve(x)
            }
        }
    }
    // 测试1,循环引用
    // let p = new Promise((resolve, reject) => {
    //     reject(0);
    // });
    // var p2 = p.then(() => { }, data => {
    //     // 循环引用,自己等待自己完成,一辈子完不成
    //     console.log('error')
    //     return p2;
    // })


    // 测试2,测试then的两个参数的返回值是promise
    function begin() {
        return new Promise(resolve => {
            setTimeout(_ => {
                console.log(333)
                resolve('first')
            }, 2000)
        })
    }

    begin().then(data => {
        console.log(data, 22)
        return new Promise(resolve => {
            resolve('jb')
        })
    }).then(res => {
        return new Promise((resolve, reject) => {
            if (Math.random() * 10 > 5) {
                reject('失败')
            } else {
                resolve('成功')
            }
        })
    }).then(res => {
        console.log(res,'成功走这')
    }, err => {
        console.log(err, '失败走这')
    })

    class Promise {
        static PENDING = 'pending'
        static FULFILLED = 'fulfilled'
        static REJECTED = 'rejected'
        constructor(excutor) {
            if (typeof excutor !== 'function') {
                throw new TypeError('类型不对')
            }
            this.state = Promise.PENDING //初始状态pending
            this.value = undefined //成功时值临时变量
            this.reason = undefined //被拒绝原因
            this.onFulfilledCallbacks = [] //成功后执行函数
            this.onRejectedCallbacks = [] //被拒绝后执行函数
            try {
                // 立即执行
                excutor(this.resolve, this.reject)
            } catch (error) {
                console.log(error)
            }
        }
        resolve = (value) => {
            // 状态不可逆
            if (this.state === Promise.PENDING) {
                this.state = Promise.FULFILLED
                this.value = value;
                // 执行then的第一个参数,把成功结果传入
                this.onFulfilledCallbacks.forEach(fn => fn(value))
            }
        }
        reject = (reason) => {
            if (this.state === Promise.PENDING) {
                // 状态为失败
                this.state = Promise.REJECTED
                this.reason = reason;
                // 被拒时执行then的第二个参数,把成功结果传入
                this.onRejectedCallbacks.forEach(fn => fn(reason))
            }
        }
        // 接受一个成功和一个失败函数
        then = (onFulfilled, onRejected) => {
            // 用户是爷爷,可能不传入onFulfilled或onRejected
            if (typeof onFulfilled !== 'function') {
                // 不是函数,就赋值一个啥也不干的函数
                onFulfilled = value => value;
            }
            if (typeof onRejected !== 'function') {
                // 失败参数不是函数,就赋值一个怎么做都是错的函数
                onRejected = reason => {
                    throw new TypeError(reason)
                }
            }
            // then方法链式调用,返回一个新的Promise对象,这个Promise对象是内部设置的,
            let promise2 = new Promise((resolve, reject) => {

                // 如果上面的Promise结果已经成功,也就是当用户传入的函数在同步代码中执行了resole()
                // 例如new Promise(resolve=>resolve('test'));这样,实际上promise已经是成功状态,只是在等then方法调用了
                if (this.state === Promise.FULFILLED) {
                    // 由于promise状态为成功,执行then的成 功回调
                    setTimeout(() => {
                        try {
                            const x = onFulfilled(this.value);
                            // 所有这里要解析一下x,看看看是啥类型
                            this.resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            console.error(error)
                        }
                    }, 0);
                }
                if (this.state === Promise.REJECTED) {
                    // 同理,失败了就执行失败回调
                    setTimeout(() => {
                        try {
                            const x = onRejected(this.reason);
                            // 所有这里要解析一下x,看看看是啥类型
                            this.resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            console.error(error)

                        }
                    }, 0);
                }
                if (this.state === Promise.PENDING) {
                    // 既没成功,又没失败。用创建promise的函数里面可能有个异步函数,在异步函数中resolve的,也可能用户根本 没想resolve()
                    // 发布订阅,将回调存好,他总会resolve的,不resolve我就不执行,resolve我就执行
                    this.onFulfilledCallbacks.push((value) => {
                        setTimeout(() => {
                            try {
                                // then函数的第一个参数是成功函数,它的返回值可能是个promise,如果是promise就拿到他的resove值
                                const x = onFulfilled(this.value);
                                // 所有这里要解析一下x,看看看是啥类型
                                this.resolvePromise(promise2, x, resolve, reject)

                            } catch (error) {
                                reject(error)
                            }
                        }, 0)
                    })
                    this.onRejectedCallbacks.push((reason) => {
                        setTimeout(() => {
                            try {
                                const x = onRejected(reason);
                                // 错误也不能大意
                                this.resolvePromise(promise2, x, resolve, reject)
                            } catch (error) {
                                reject(reason)
                            }
                        }, 0)
                    })
                }
            })
            // 别忘了return 这孙子
            return promise2;

        }
        resolvePromise = (promise2, x, resolve, reject) => {
            // 怕他把then的返回 值扔回
            if (promise2 === x) {
                throw new TypeError('循环引用是干啥?')
            }
            // 保证只执行一次
            let called = false;
            //判断是否为Promise
            if (x instanceof Promise) {
                // x若是promise,就then它一下,它的reslove就是咱们要reslove的值
                x.then(value => {
                    // 不敢保证用户嵌套几层promise,检验一下没错
                    this.resolvePromise(promise2, value, resolve, reject)
                },
                    reason => {
                        reject(reason)
                    })
            } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
                // x不是普通值,对象或者方法
                try {
                    // x是对象,并且then属性是function
                    if (typeof x.then === 'function') {
                        const then = x.then;
                        then((value) => {
                            if (called) return
                            called = true;
                            // 继续递归
                            this.resolvePromise(promise2, value, resolve, reject)
                        }, reason => {
                            if (called) return
                            called = true;
                            reject(reason)
                        })
                    } else {
                        if (called) return
                        called = true
                        // 不是promise,也不是thenable对象,啥也不是就直接resolve吧
                        resolve(x)
                    }
                } catch (e) {
                    if (called) return
                    called = true
                    // 报错就reject
                    reject(e)
                }
            } else {
                if (called) return
                called = true
                // 啥也不是就直接resolve吧
                resolve(x)
            }
        }
    }
    // 测试1,循环引用
    let p = new Promise((resolve, reject) => {
        reject(0);
    });
    var p2 = p.then(() => { }, data => {
        // 循环引用,自己等待自己完成,一辈子完不成
        console.log('error')
        return p2;
    })


    // 测试2,测试then的两个参数的返回值是promise
    function begin() {
        return new Promise(resolve => {
            setTimeout(_ => {
                console.log(333)
                resolve('first')
            }, 2000)
        })
    }

    begin().then(data => {
        console.log(data, 22)
        return new Promise(resolve => {
            resolve('jb')
        })
    }).then(res => {
        return new Promise((resolve, reject) => {
            if (Math.random() * 10 > 5) {
                reject('失败')
            } else {
                resolve('成功')
            }
        })
    }).then(res => {
        console.log(res,'成功走这')
    }, err => {
        console.log(err, '失败走这')
    })


    // function begin() {
    //     return new Promise(resolve => {

    //         resolve('first')

    //     })
    // }

    // begin().then(data => {

    //     return {
    //         then: resolve => {
    //             resolve('jb')
    //         }
    //     }
    // }).then(res => {
    //     console.log(res)
    //     return new Promise((resolve, reject) => {
    //         if (Math.random() * 10 > 5) {
    //             reject('失败')
    //         } else {
    //             resolve('成功')
    //         }
    //     })
    // }).then(res => {
    //     console.log(res, '成功走这')
    // }, err => {
    //     console.log(err, '失败走这')
    // })

稍微完整版

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">

<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>

<body>

</body>
<script>
   // 看了好多例子,调试3天


   class Promise {
       static PENDING = 'pending'
       static FULFILLED = 'fulfilled'
       static REJECTED = 'rejected'
       //resolve方法
       static resolve = function (val) {
           return new Promise((resolve, reject) => {
               resolve(val)
           });
       }
       //reject方法
       static reject = function (val) {
           return new Promise((resolve, reject) => {
               reject(val)
           });
       }
       //race方法 
       static race = function (promises) {
           return new Promise((resolve, reject) => {
               for (let i = 0; i < promises.length; i  ) {
                   promises[i].then(resolve, reject)
               };
           })
       }
       //all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
       static all = function (promises) {
           let arr = [];
           // 这个i是独立的,当他等于promises.length时,是说明所有的异步都完成了
           let i = 0;
           function processData(index, data, resolve) {
               arr[index] = data;
               i  ;
               if (i == promises.length) {
                   resolve(arr);
               };
           };
           return new Promise((resolve, reject) => {
               for (let i = 0; i < promises.length; i  ) {
                   promises[i].then(data => {
                       processData(i, data, resolve);

                   }, reject);
               };
           });
       }
       constructor(excutor) {
           if (typeof excutor !== 'function') {
               throw new TypeError('类型不对')
           }
           this.state = Promise.PENDING //初始状态pending
           this.value = undefined //成功时值临时变量
           this.reason = undefined //被拒绝原因
           this.onFulfilledCallbacks = [] //成功后执行函数
           this.onRejectedCallbacks = [] //被拒绝后执行函数

           try {
               // 立即执行
               excutor(this.resolve, this.reject)
           } catch (error) {
               console.log(error)
           }
       }
       resolve = (value) => {
           // 状态不可逆
           if (this.state === Promise.PENDING) {
               this.state = Promise.FULFILLED
               this.value = value;
               // 执行then的第一个参数,把成功结果传入
               this.onFulfilledCallbacks.forEach(fn => fn(value))
           }
       }
       reject = (reason) => {
           if (this.state === Promise.PENDING) {
               // 状态为失败
               this.state = Promise.REJECTED
               this.reason = reason;
               // 被拒时执行then的第二个参数,把成功结果传入
               this.onRejectedCallbacks.forEach(fn => fn(reason))
           }
       }
       // 接受一个成功和一个失败函数
       then = (onFulfilled, onRejected) => {
           // 用户是爷爷,可能不传入onFulfilled或onRejected
           if (typeof onFulfilled !== 'function') {
               // 不是函数,就赋值一个啥也不干的函数
               onFulfilled = value => value;
           }
           if (typeof onRejected !== 'function') {
               // 默认的onRejected,不做reject处理,是他pending中
               onRejected = reason => {
                   throw reason
               }
           }
           // then方法链式调用,返回一个新的Promise对象,这个Promise对象是内部设置的,
           let promise2 = new Promise((resolve, reject) => {

               // 如果上面的Promise结果已经成功,也就是当用户传入的函数在同步代码中执行了resole()
               // 例如new Promise(resolve=>resolve('test'));这样,实际上promise已经是成功状态,只是在等then方法调用了
               if (this.state === Promise.FULFILLED) {
                   // 由于promise状态为成功,执行then的成 功回调
                   setTimeout(() => {
                       try {
                           const x = onFulfilled(this.value);
                           // 所有这里要解析一下x,看看看是啥类型
                           this.resolvePromise(promise2, x, resolve, reject)
                       } catch (error) {
                           reject(error)
                       }
                   }, 0);
               }
               if (this.state === Promise.REJECTED) {
                   // 同理,失败了就执行失败回调
                   setTimeout(() => {
                       try {
                           const x = onRejected(this.reason);
                           // 所有这里要解析一下x,看看看是啥类型
                           this.resolvePromise(promise2, x, resolve, reject)
                       } catch (error) {

                           reject(error)

                       }
                   }, 0);
               }
               if (this.state === Promise.PENDING) {
                   // 既没成功,又没失败。用创建promise的函数里面可能有个异步函数,在异步函数中resolve的,也可能用户根本 没想resolve()
                   // 发布订阅,将回调存好,他总会resolve的,不resolve我就不执行,resolve我就执行
                   this.onFulfilledCallbacks.push((value) => {
                       setTimeout(() => {
                           try {
                               // then函数的第一个参数是成功函数,它的返回值可能是个promise,如果是promise就拿到他的resove值
                               const x = onFulfilled(this.value);
                               // 所有这里要解析一下x,看看看是啥类型
                               this.resolvePromise(promise2, x, resolve, reject)

                           } catch (error) {
                               reject(error)
                           }
                       }, 0)
                   })
                   this.onRejectedCallbacks.push((reason) => {
                       setTimeout(() => {
                           try {
                               const x = onRejected(reason);
                               // 错误也不能大意
                               this.resolvePromise(promise2, x, resolve, reject)
                           } catch (error) {
                               reject(reason)
                           }
                       }, 0)
                   })
               }
           })
           // 别忘了return 这孙子
           return promise2;

       }
       resolvePromise = (promise2, x, resolve, reject) => {
           // 怕他把then的返回 值扔回
           if (promise2 === x) {
               throw new TypeError('循环引用是干啥?')
           }
           // 保证只执行一次
           let called = false;
           //判断是否为Promise
           if (x instanceof Promise) {
               // x若是promise,就then它一下,它的reslove就是咱们要reslove的值
               x.then(value => {
                   // 不敢保证用户嵌套几层promise,检验一下没错

                   this.resolvePromise(promise2, value, resolve, reject)
               },
                   reason => {
                       this.resolvePromise(promise2, reason, resolve, reject)

                       // reject(reason)
                   })
           } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
               // x不是普通值,对象或者方法
               try {
                   // x是对象,并且then属性是function
                   if (typeof x.then === 'function') {
                       const then = x.then;
                       then((value) => {
                           if (called) return
                           called = true;
                           // 继续递归
                           this.resolvePromise(promise2, value, resolve, reject)
                       }, reason => {
                           if (called) return
                           called = true;
                           reject(reason)
                       })
                   } else {
                       if (called) return
                       called = true
                       // 不是promise,也不是thenable对象,啥也不是就直接resolve吧
                       resolve(x)
                   }
               } catch (e) {
                   if (called) return
                   called = true
                   // 报错就reject
                   reject(e)
               }
           } else {
               if (called) return
               called = true

               // 啥也不是就直接resolve吧
               resolve(x)
           }
       }
       //then的时候 如果不传入onRejected参数,那么会默认一个
       catch = (onRjected) => {
           this.then(null, onRjected)
       }
   }
   // // 测试1,循环引用
   // let p = new Promise((resolve, reject) => {
   //     reject(0);
   // });
   // var p2 = p.then(() => { }, data => {
   //     // 循环引用,自己等待自己完成,一辈子完不成
   //     console.log('error')
   //     return p2;
   // })


   // 测试2,测试then的两个参数的返回值是promise
   // function begin() {
   //     return new Promise((resolve, reject) => {
   //         if (10 > 5) {
   //             reject('失败')
   //         } else {
   //             resolve('成功')
   //         }
   //     })
   // }

   // begin().then((res) => {
   //     console.log(res, '成功走这')
   // }
   //     , err => {
   //         console.log(err, '失败走这')
   //     }
   // )
   //     .catch(e => {
   //         console.log(e, 'catch走着')
   //     })



   // function begin() {
   //     return new Promise(resolve => {

   //         resolve('first')

   //     })
   // }

   // begin().then(data => {

   //     return {
   //         then: resolve => {
   //             resolve('jb')
   //         }
   //     }
   // }).then(res => {
   //     console.log(res)
   //     return new Promise((resolve, reject) => {
   //         if (Math.random() * 10 > 5) {
   //             reject('失败')
   //         } else {
   //             resolve('成功')
   //         }
   //     })
   // }).then(res => {
   //     console.log(res, '成功走这')
   // }, err => {
   //     console.log(err, '失败走这')
   // })

   // dataSource.forEach(item => {
   //     const { testValue } = item.paramsMetaDTO;
   //     tags.map(tag => {
   //         tag.label
   //     })

   // })
   var a = new Promise((resolve, reject) => {
       setTimeout(() => {
           resolve('1牛逼牛逼')
       }, 3);
   })
   var b = new Promise((resolve, reject) => {
       setTimeout(() => {
           resolve('2牛逼牛逼')
       }, 1);
   })
   Promise.all([a, b]).then(res => {
       console.log(res, '这是结果');
   })
</script>

</html>

0 人点赞