前端手撕代码——手撕promise

文章详细介绍了如何用JavaScript实现一个简易的Promise类,包括状态管理(PENDING,FULFILLED,REJECTED)、回调函数的存储与执行、错误处理以及防止链式调用时的循环引用问题。
摘要由CSDN通过智能技术生成
class MyPromise{
    static PENDING = 'pending';
    static FULFILLED = 'fulfilled';
    static REJECTED = 'rejected';

    constructor(executor){
        this.status = MyPromise.PENDING;
        this.result = null;
        this.onFulfilled = [];// 成功的回调
        this.onRejected = [];// 失败的回调


        let resolve = result => {
            if(this.status === MyPromise.PENDING){
                this.status = MyPromise.FULFILLED;
                this.result = result;
                this.onFulfilled.forEach(fn => fn());
            }
        }

        let reject = result => {
            if(this.status === MyPromise.PENDING){
                this.status = MyPromise.REJECTED;
                this.result = result;
                this.onRejected.forEach(fn => fn());
            }
        }

        // 使用try catch 方式实例对象的时候报错 产生异常
        try{
            executor(resolve, reject);
        }catch(err){
            this.reject(err);
        }
    }

    // promise执行then的时候可以不传入回调函数,class会给默认的回调函数
    then(onFulfilled, onRejected){
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
        onRejected = typeof onRejected === 'function' ? onRejected : v => {throw v};
        
        let self = this;

        let promise2 = new MyPromise((resolve, reject) => {
            const handle = callback => {
                setTimeout(() => {
                    try {
                        const x = callback(self.result);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch(e) {
                        reject(e);
                    }
                })
            }
            if(self.status === MyPromise.PENDING){
                self.onFulfilled.push(handle(onFulfilled));
                self.onRejected.push(handle(onRejected));
            }     
            if(self.status === MyPromise.FULFILLED){
                handle(onFulfilled);
            }
            if(self.status === MyPromise.REJECTED){
                handle(onRejected);
            }
        })
    }

    // promise执行then的时候可以不传入回调函数,class会给默认的回调函数
    then2(onFulfilled, onRejected){
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
        onRejected = typeof onRejected === 'function' ? onRejected : v => {throw v};
        
        let promise2 = new MyPromise((resolve, reject) => {
            if(this.status === MyPromise.PENDING){
                self.onFulfilled.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onFulfilled(this.result);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch(e) {
                            reject(e);
                        }
                    }, 0);
                });
                self.onRejected.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onRejected(this.result);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch(e) {
                            reject(e);
                        }
                    }, 0);
                });
            }     
            if(this.status === MyPromise.FULFILLED){
                setTimeout(() => {
                    try {
                        const x = onFulfilled(this.result);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch(e) {
                        reject(e);
                    }
                }, 0);
            }
            if(this.status === MyPromise.REJECTED){
                setTimeout(() => {
                    try {
                        const x = onRejected(this.result);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch(e) {
                        reject(e);
                    }
                }, 0);
            }
        })
    }
}

function resolvePromise(promise, x, resolve, reject){
    if(promise2 === x){
        return reject(new TypeError('Chaining cycle detected'));
    }
    let called;

    if((typeof x === 'object' && x !== null) || typeof x === 'function'){
        try{
            let then = x.then;
            if(typeof then !== 'function'){
                then.call(x, y => {
                    if(called) return;
                    called =  true;
                    resolvePromise(promise, y, resolve, reject);
                }, e => {
                    if(called) return;
                    called = true;
                    reject(e);
                })
            }else{
                resolve(x);
            }
        }catch(e){
            if(called) return;
            called = true;
            reject(e);
        }
    }else {
        resolve(x);
    }
}

// 这里参数里的resolve 和 reject可以理解为工具,可以修改promise的状态
// 是class自带的工具,因此需要在class中定义
let promise = new MyPromise((resolve, reject) => {});

promise.then(success => {}, err => {});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值