js手写promise

JS手写Promise

Promise是异步编程的一种解决方案,简单的来说,Promise作为一个容器,保存着某个未来才会结束的事件的结果。

Promise有两个特点:

1)对象的状态不受外界影响。Promise有三种状态:pengding(进行中),fulfilled(完成),rejected(失败),只有异步操作的结果,可以决定当前是哪一个状态。

2)一旦状态改变,就不再改变。


class MyPromise {
    
    
    static PENDING = 'pending';
    static FULFILLED = 'fulfilled';
    static REJECTED = 'rejected';
    constructor(executor) {
    
     // executor 执行器
        this.status = MyPromise.PENDING; // 状态
        this.value = undefined; // 成功值
        this.reason = undefined; // 失败理由
        this.onFulfilled = [];
        this.onRejected = [];

        try {
    
    
            executor(this.resolve.bind(this), this.reject.bind(this));
        } catch (err) {
    
    
            this.reject(err);
        }
    }
    resolve(value) {
    
    
        if (this.status === MyPromise.PENDING) {
    
    
            setTimeout(() => {
    
    
                this.status = MyPromise.FULFILLED;
                this.value = value;
                this.onFulfilled.forEach(fn => fn(value));
            }, 0)
        }
    }

    reject(reason) {
    
    
        if (this.status === MyPromise.PENDING) {
    
    
            setTimeout(() => {
    
    
                this.status = MyPromise.REJECTED;
                this.reason = reason;
                this.onRejected.forEach(fn => fn(reason))
            }, 0)
        }
    }
    then(onFulfilled, onRejected) {
    
    
        return new MyPromise((resolve, reject) => {
    
    
            let handler = (callback) => {
    
    
                try {
    
    
                    let result = callback(this.value);
                    if (result instanceof MyPromise) {
    
     // 如果结果是Promise
                        result.then(resolve, reject); // 返回一个Promise
                    } else {
    
     // 如果结果不是Promise
                        resolve(result);// 直接resolve 结果
                    }
                } catch (err) {
    
    
                    reject(err)
                }
            }
            if (this.status === MyPromise.FULFILLED) {
    
    
                handler(onFulfilled)
            }

            if (this.status === MyPromise.REJECTED) {
    
    
                handler(onRejected)
            }

            if (this.status === MyPromise.PENDING) {
    
    
                typeof onFulfilled == 'function' && this.onFulfilled.push(onFulfilled)
                typeof onRejected == 'function' && this.onRejected.push(onRejected)
            }
        });
    }

    static resolve(promises) {
    
    
        if (promises instanceof MyPromise) {
    
     // 如果参数是MyPromise 实例,那么MyPromise.resolve将不做任何修改、原封不动地返回这个实例。
            return promises;
        } else if (typeof promises.then === 'function') {
    
    
            return new MyPromise((resolved, rejected) => {
    
    
                try {
    
    
                    promises.then(resolved, rejected);
                } catch (err) {
    
    
                    rejected(err);
                }
            })
        } else {
    
    
            // 如果参数是一个原始值,或者是一个不具有then()方法的对象
            // Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved
            return new MyPromise((resolved, rejected) => {
    
    
                resolved(promises);
            })
        }
    }

    static reject(reason) {
    
    
        return new MyPromise((resolved, rejected) => {
    
    
            rejected(reason);
        })
    }

    static all(promises) {
    
    
        if (!Utils.isIterable(promises)) {
    
    
            throw new TypeError("Object is not iterable");
        }
        let values = [];
        return new MyPromise((resolved, rejected) => {
    
    
            promises.map(v => {
    
    
                let item = v;
                if (!(v instanceof MyPromise)) item = MyPromise.resolve(item)
                item.then(res => {
    
    
                    values.push(res);
                    if (values.length == promises.length) {
    
    
                        resolved(res);
                    }
                }, err => {
    
    
                    rejected(err)
                })
            })
        })
    }

    static race(promises) {
    
    
        if (!Utils.isIterable(promises)) {
    
    
            throw new TypeError("Object is not iterable");
        }
        return new MyPromise((resolved, rejected) => {
    
    
            promises.map(v => {
    
    
                let item = v;
                if (!(v instanceof MyPromise)) item = MyPromise.resolve(item)
                item.then(res => {
    
    
                    resolved(res);
                }, error => {
    
    
                    rejected(error);
                })
            })
        })
    }

    catch(rejected) {
    
    
        this.then(undefined, rejected)
    }

    finally(callback) {
    
    
        let P = this.constructor;
        return this.then(
            value => P.resolve(callback()).then(() => value),
            reason => P.resolve(callback()).then(() => {
    
     throw reason })
        )
    }
}

class Utils {
    
     // 工具类
    static isIterable(object) {
    
     // object是否可迭代
        return typeof object[Symbol.iterator] === 'function'
            && typeof object[Symbol.iterator]() === 'object'
            && typeof object[Symbol.iterator]().next === 'function'
    }
}

猜你喜欢

转载自blog.csdn.net/yuanqi3131/article/details/122199055