自定义实现Promise

Promise是很重要的知识点,必须牢记于心,下面是自定义实现的Promise:

class MyPromise {
    //定义promise的3个状态
    //初始状态,既不是完成,也不是失败
    static PENDING = "pending";
    //操作成功的状态
    static FULFILLED = "fulfilled";
    //操作失败的状态
    static REJECTED = "rejected";
    constructor(excutor) {
        //初始化状态
        this.status = MyPromise.PENDING;
        //需要保存的回调函数
        this.callbacks = [];
        //初始值
        this.value = undefined;
        //
        try {
            // 调用excutor函数,注意resolve和reject的this在严格模式下是undefined
            //要将当前的this传入给resolve和reject,形成新的函数
            excutor(this.resolve.bind(this), this.reject.bind(this));
        } catch (error) {
            //将捕获的错误交给reject()函数
            this.reject(error);
        }
    }
    //成功时
    resolve(value) {
        //只有当为初始状态才进行
        if (this.status === MyPromise.PENDING) {
            //当成功时,修改状态,并赋值
            this.status = MyPromise.FULFILLED;
            this.value = value;
            //在setTimeout()中抛出,并且是异步的
            setTimeout(() => {
                this.callbacks.forEach(callback => {
                    callback.onResolve(value);
                })
            })
        }
    }
    //失败时
    reject(reason) {
        //只有当为初始状态才进行
        if (this.status === MyPromise.PENDING) {
            //当失败时,修改状态,并赋值
            this.status = MyPromise.REJECTED;
            this.value = reason;
            //在setTimeout()中抛出,并且是异步的
            setTimeout(() => {
                this.callbacks.forEach(callback => {
                    callback.onRejected(value);
                })
            })
        }
    }
    then(onResolve, onRejected) {
        //注意如果并没有传入函数时,默认设置为一个空函数,并将当前值保存下来
        //then具有穿透功能
        //如 let p = new Promise((resolve,reject)=>{
        //     resolve("成功")
        // })
        // p.then().then(value=>console.log(value)) //=>成功
        if (typeof onResolve !== "function") {
            onResolve = () => this.value;
        }
        if (typeof onRejected !== "function") {
            onRejected = () => this.value;
        }
        //返回的是MyPromise对象
        let promise = new MyPromise((resolve, reject) => {
            //如果为成功状态
            if (this.status === MyPromise.FULFILLED) {
                this.parse(promise, onResolve(this.value), resolve, reject);
            }
            if (this.status === MyPromise.REJECTED) {
                this.parse(promise, onRejected(this.value), resolve, reject);
            }
            // 如果resolve()是在setTimeout()中进行的
            // 如 let p = new Promise((resolve, reject) => {
            //     setTimeout(() => {
            //         resolve("成功")
            //     }, 100);
            // })
            // p.then(value => console.log(value)) //=>成功
            //需要把当前需要进行的函数保存下来
            if (this.status === MyPromise.PENDING) {
                this.callbacks.push({
                    onResolve: value => {
                        this.parse(promise, onResolve(value), resolve, reject);
                    },
                    onRejected: value => {
                        this.parse(promise, onRejected(value), resolve, reject);
                    }
                })
            }
        })
        return promise;
    }
    parse(promise, result, resolve, reject) {
        setTimeout(() => {
            //自己调用自己时,抛出错误
            if (promise === result) {
                throw new TypeError("Chaining cycle detected");
            }
            try {
                //将当前return的值抛出,让下一个then接收
                //如果return的值是MyPromise对象则return出常数
                if (result instanceof MyPromise) {
                    //成功的交给resolve(),失败的交给reject()
                    // result.then(
                    //     value => {
                    //         resolve(value);
                    //     },
                    //     reason => {
                    //         reject(reason);
                    //     }
                    // )
                    //等于下面
                    result.then(resolve, reject);
                } else {
                    resolve(this.value);
                }

            } catch (error) {
                //抛给下一个then
                reject(error);
            }
        })
    }
    static resolve(value) {
        return new MyPromise((resolve, reject) => {
            if (value instanceof MyPromise) {
                value.then(resolve, reject);
            } else {
                resolve(value);
            }
        })
    }
    static reject(value) {
        return new MyPromise((resolve, reject) => {
            //如果当前的值是MyPromise对象,则返回它的值
            if (value instanceof MyPromise) {
                value.then(resolve, reject);
            } else {
                reject(value);
            }
        })
    }
    //当所有的promise都成功返回时才返回
    static all(promises) {
        const values = [];
        return new MyPromise((resolve, reject) => {
            promises.forEach(promise => {
                promise.then(
                    value => {
                        values.push(value);
                        //如果都返回成功才返回
                        if (values.length === promises.length) {
                            resolve(values);
                        }
                    },
                    reason => {
                        //当有个失败的值便返回这个失败的值
                        reject(reason);
                    }
                )
            })
        });
    }
    //当有一个promise成功返回时便返回这个promise
    static race(promises) {
        return new MyPromise((resolve, reject) => {
            promises.forEach(promise => {
                promise.then(
                    value => {
                        //有一个成功便返回
                        resolve(value);
                    },
                    reason => {
                        //有一个失败就返回
                        reject(reason);
                    }
                )
            })
        });
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值