Promise

手写Promise,从入门到毕业

根据PromiseA+规范实现此代码,注意:Promise的异步任务是浏览器的quenemicrotask API实现的,此代码并没使用此API,代码只实现基本功能;渡一教育yyds!!!

1.手写promise构造器

enum Status{
    PENDING = "pending",
    FULFILLED = "fulfilled",
    REJECTED = "rejected"
}

class IPromise{
    private _status:string = Status.PENDING;
    private _result:any = undefined;
    constructor(executer:Function){
        
        const resolve:Function = (data)=>{
            this.changeStatus(Status.FULFILLED,data)
        };
        const reject:Function = (reason)=>{
            this.changeStatus(Status.REJECTED,reason)
        };
        //只能捕获同步error
        try {
            executer(resolve,reject);
            
        } catch (error) {
            reject(error)
        }

    }
    private changeStatus(status:string,result:any){
        if(this._status !== Status.PENDING) return;
        this._status = status;
        this._result = result; 
    }
}
(1)Status 是一个枚举类型,用于表示 Promise 的状态。该枚举类型定义了三个常量:PENDING、FULFILLED、REJECTED,分别表示 Promise 的三种状态。
(2)IPromise 类是 Promise 实现的核心部分。在构造函数中,它接收一个执行器(executor)函数作为参数,并将其保存在内部变量中。该执行器函数包含两个回调函数 resolve 和 reject,分别用于异步操作成功和失败时的处理。当 Promise 被创建时,执行器函数会立即执行。
(3)在 IPromise 类中,定义了两个私有变量 _status 和 _result,分别用于保存 Promise 的状态和结果。初始状态为 PENDING,结果为 undefined。在实现过程中,需要注意保证 Promise 状态不可逆。
(4)changeStatus 方法是一个私有方法,用于修改 Promise 的状态和结果。如果 Promise 已经处于非 PENDING 状态,就不再进行状态的更新。
(5)在 executer 函数中,只能捕获同步错误。如果发生异步错误,需要在回调函数中进行错误处理,否则会导致程序崩溃。

2.Promise核心then方法

enum Status {
    PENDING = "pending",
    FULFILLED = "fulfilled",
    REJECTED = "rejected"
}

class IPromise {
    private _status: string = Status.PENDING;
    private _result: any = undefined;
    private Handlers = [];
    constructor(executer: Function) {

        const resolve: Function = (data) => {
            this.changeStatus(Status.FULFILLED, data)
        };
        const reject: Function = (reason) => {
            this.changeStatus(Status.REJECTED, reason)
        };
        //只能捕获同步error
        try {
            executer(resolve, reject);

        } catch (error) {
            reject(error)
        } 

    }
    private changeStatus(status: string, result: any) {
        if (this._status !== Status.PENDING) return;
        this._status = status;
        this._result = result;
        this.run();
    }
    //A+规范方法
    then(onFulfilled?, onReject?) {
        return new IPromise((resolve, reject) => {
            this.Handlers.push({
                onFulfilled,
                onReject,
                resolve,
                reject
            })
            this.run()
        })
    }
    private runOne(callback, resolve, reject) {
        //将任务加到微队列
        this.runMicroTask(() => {
            if (typeof callback !== "function") {
                const setted = this._status === Status.FULFILLED ? resolve : reject;
                setted(this._result);
                return;
            }
            try {
                const data = callback(this._result);
                if (this.isPromise(data)) {
                    data.then(resolve, reject);
                } else {
                    resolve(data);
                }

            } catch (error) {
                reject(error);
            }
        })

    }
    private run() {
        if (this._status === Status.PENDING) return;
        while (this.Handlers.length) {
            const { onFulfilled, onReject, resolve, reject } = this.Handlers.shift();
            if (this._status === Status.FULFILLED) {
                this.runOne(onFulfilled, resolve, reject);
            } else {
                this.runOne(onReject, resolve, reject);
            }


        }

    }
    private isPromise(val) {
        if (val !== null && typeof val === "function" || "object") {
            return typeof val.then === "function";
        }
        return false;
    }
    private runMicroTask(fn) {
        //此处可以使用前文提到的API
        if (typeof process === "object" && typeof process.nextTick === "function") {
            process.nextTick(fn);
        } else if (typeof queueMicrotask === "function") {

            queueMicrotask(fn)

        } else {
            setTimeout(fn, 0)
        }
    }
}

3.es6定义方法,具体函数实现方法需要查看mdn官方文档

//es6规定promise方法
    catch(onReject) {
        return this.then(undefined, onReject)
    }
    finlly(onFinally) {
        return this.then((data) => {
            onFinally();
            return data;
        }, (err) => {
            onFinally();
            throw err;
        })

    }
    static resolve(val) {
        if (val instanceof IPromise) return val;
        let _resolve, _reject;
        const p = new IPromise((resolve,reject)=>{
            _resolve = resolve;
            _reject = reject
        })
        if(p.isPromise(val)){
            val.then(_resolve,_reject)
        }else{
            _resolve(val);
        }
        return p;
    }
    static reject(reason) {
        return new IPromise((resolve,reject)=>{
            reject(reason);
        })
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值