手写Promise源码

class MyPromise {
    //三个状态
    //失败
    static REJECTED = 'rejected'
    //等待
    static PENDING = 'pending'
    //成功
    static FULFILLED = 'fulfilled'

    //值
    value = undefined
    //默认状态
    status = MyPromise.PENDING
    //成功回调队列
    onFulfilledCallBacks = []
    //失败回调队列
    onRejectedCallBacks = []

    //构造函数
    constructor(execute) {
        //成功执行的回调
        const resolve = (value) => {
            if (this.status === MyPromise.PENDING) {
                this.value = value
                this.status = MyPromise.FULFILLED
                this.onFulfilledCallBacks.forEach((func) => {
                    func(value)
                })
            }
        }

        //失败执行的回调
        const reject = (value) => {
            if (this.status === MyPromise.PENDING) {
                this.value = value
                this.status = MyPromise.REJECTED
                this.onRejectedCallBacks.forEach((func) => {
                    func(value)
                })
            }
        }

        //出现异常则执行reject回调
        try {
            execute(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }

    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (onFulfilled) => onFulfilled
        onRejected = typeof onRejected === 'function' ? onRejected : (onRejected) => onRejected
        return new MyPromise((resolve, reject) => {
            //处理已完成状态
            if (this.status === MyPromise.FULFILLED) {
                try {
                    //微任务队列,这是js自带的一个队列,无需定义
                    queueMicrotask(() => {
                        const result = onFulfilled(this.value)
                        // console.log(result);
                        this.handlePromiseResult(result, resolve, reject)
                    })
                } catch {
                    reject(error)
                }
            }
            //处理已拒绝的状态
            else if (this.status === MyPromise.REJECTED) {
                try {
                    queueMicrotask(() => {
                        const result = onRejected(this.value)
                        this.handlePromiseResult(result, resolve, reject)
                    })
                } catch (error) {
                    reject(error)
                }
            }
            //处理异步状态
            else {
                this.onFulfilledCallBacks.push((value) => {
                    queueMicrotask(() => {
                        const result = onFulfilled(value)
                        this.handlePromiseResult(result, resolve, reject)
                    })
                })
                this.onRejectedCallBacks.push((value) => {
                    queueMicrotask(() => {
                        const result = onFulfilled(value)
                        this.handlePromiseResult(result, resolve, reject)
                    })
                })
            }
        })
    }

    catch = (onRejected) => {
        return this.then(null, onRejected);
    }

    //处理结果,为了支持链式调用then方法
    handlePromiseResult(result, resolve, reject) {
        if (result instanceof MyPromise) {
            result.then(resolve, reject)
        } else {
            resolve(result)
        }
    }

    static resolve = (value) => {
        return new MyPromise((resolve, reject) => {
            resolve(value)
        })
    }

    static reject = (value) => {
        return new MyPromise((resolve, reject) => {
            reject(value)
        })
    }


    /* all 方法接收一个 Promise 数组,返回一个新的 Promise。
    只有当所有输入的 Promise 都解决时,新 Promise 才会解决,
    并返回包含所有 Promise 结果的数组;否则,只要有一个 Promise 拒绝,
    新 Promise 就会被拒绝。 */
    static all = (promises) => {
        if (!this._hasIterator(promises)) {
            throw new Error('参数不可迭代');
        }

        return new MyPromise((resolve, reject) => {
            const resultArr = [];
            //forEach方法不能使用break跳出循环,只能抛出错误才能跳出循坏
            promises.forEach((promise) => {
                try {
                    if (!this.isPromise(promise)) {
                        throw new Error('非Promise对象')
                    }
                } catch (error) {
                    console.warn(error);
                }
                promise.then(
                    (res) => {
                        resultArr.push(res);
                        if (resultArr.length === promises.length) {
                            resolve(resultArr);
                        }

                    },
                    (err) => {
                        reject(err);
                    }
                );
            });
        });
    };


    /* allSettled 方法返回一个 Promise,该 Promise 在所有给定的 Promise 都已经解决或拒绝后解决。
    它会等待所有的 Promise 完成,无论成功还是失败,并返回一个包含每个 Promise 结果的数组。 */
    static allSettled = (promises) => {
        if (!this._hasIterator(promises)) {
            throw new Error('参数不可迭代')
        }

        return new MyPromise((resolve) => {
            const resultArr = []
            promises.forEach((promise) => {
                try {
                    if (!this.isPromise(promise)) {
                        throw new Error('非Promise对象')
                    }
                } catch (error) {
                    console.warn(error);
                }
                promise.then(
                    (res) => {
                        resultArr.push({ status: 'fulfilled', value: res })
                        if (resultArr.length === promises.length) {
                            resolve(resultArr)
                        }
                    },
                    error => {
                        resultArr.push({ status: 'rejected', reason: error })
                        if (resultArr.length === promises.length) {
                            //这里调用的是resolve,成功的回调
                            resolve(resultArr)
                        }
                    }
                )
            })
        })
    }

    // race 方法返回一个 Promise,该 Promise 在给定的任意 Promise 解决或拒绝后立即解决。
    static race = (promises) => {
        if (!this._hasIterator(promises)) {
            throw new Error('参数不可迭代')
        }
        return new MyPromise((resolve, reject) => {
            
            promises.forEach((promise) => {
                try {
                    if (!this.isPromise(promise)) {
                        throw new Error('非Promise对象')
                    }
                } catch (error) {
                    console.warn(error);
                }
                promise.then(
                    (res) => {
                        resolve(res)
                    },
                    (error) => {
                        reject(error)
                    }
                )
            })
        })
    }

    //与race方法不同,any方法在给定的第一个promise解决后立即解决
    static any = (promises) => {
        if (!this._hasIterator(promises)) {
            throw new Error('参数不可迭代')
        }

        return new MyPromise((resolve, reject) => {
            promises.forEach((promise) => {
                try {
                    if (!this.isPromise(promise)) {
                        throw new Error('非Promise对象')
                    }
                } catch (error) {
                    console.warn(error);
                }
                promise.then((res) => {
                    resolve(res)
                })
            })
        })
    }

    //为了方便创建一个延迟解决的 Promise 对象,我们添加了 deferred 方法
    static deferred = () => {
        let dfd = {}
        dfd.promise = new MyPromise((resolve, reject) => {
            dfd.resolve = resolve;
            dfd.reject = reject
        })
        return dfd
    }

    static _hasIterator = (obj) => {
        return Object.getPrototypeOf(obj).hasOwnProperty(Symbol.iterator)
    }

    //判断是否位promise对象
    static isPromise(value) {
        return (
            value instanceof MyPromise ||
            (typeof value === "object" &&
                value !== null &&
                typeof value.then === "function")
        );
    }

}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值