前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次就想搞懂这个Promise

一次就想搞懂这个Promise

作者头像
刘嘿哈
发布2022-10-25 14:06:26
6050
发布2022-10-25 14:06:26
举报
文章被收录于专栏:js笔记

看了好多例子,调试了很久,结果和内置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>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档