Promise封装

188 阅读1分钟

Promise概念

Promise,字面意思是一个承诺,实际是为了解决异步回调地狱问题提出的方案。在没有Promise的异步回调中很容易行程下面结果:

    fetchData(url, res1 => {
        fetchData(res1.url, res2 => {
            fechData(res2.url, res3 => {
                console.log(res3)
                ...
            }
        }
    })

Promise的出现,不仅提供了异步解决方案,还提供了链式调用方便了阅读和书写。

封装Promise

class myPromise {
    promiseState = 'pedding';
    promiseResult;
    callbacks = [];
    catchHandler;
    executor;

    constructor(executor) {
        this.executor = executor;
        this.executor(this.onResolve.bind(this), this.onReject.bind(this));
    };

    onResolve(res) {
        this.promiseState = 'resolved';
        this.promiseResult = res;
        // 当状态改变为【成功】时,执行所有成功回调
        this.callbacks.forEach(item => item.resovleCallBack(res));
        return this.promiseResult;
    };

    onReject(err) {
        this.promiseState = 'rejected';
        this.promiseResult = err;
        // 当状态改变为【失败】时,执行所有失败回调
        this.callbacks.forEach(item => item.rejectCallBack(err));
        if (this.catchHandler) {
            this.catchHandler(err);
        }
        return this.promiseResult;
    };

    then(onResolve, onReject) {
        let self = this;
        // 返回新的promise对象
        return new myPromise((resovle, reject) => {
            switch (self.promiseState) {
                case 'resolved':
                    resovle(onResolve(self.promiseResult));
                    break;
                case 'rejected':
                    reject(onReject(self.promiseResult));
                    break;
                // 处理异步
                case 'pedding':
                    self.callbacks.push({
                        resovleCallBack: function (res) {
                            resovle(onResolve(res));
                        },
                        rejectCallBack: function (err) {
                            reject(onReject(err));
                        }
                    });
            }
        })
    };

    catche(onReject) {
        // 如果当前Promise实例状态 不为【rejected】时,返回当前实例
        if (this.promiseState !== 'rejected') {
            return this;
        }
        return new myPromise((resovle, reject) => {
            // 处理异常穿透
            this.catchHandler = function (err) {
                onReject(err);
                reject(err);
            }
        });
    }


    static resolve(res) {
        return new myPromise((resolve, reject) => {
            resolve(res);
        });
    };

    static reject(err) {
        return new myPromise((resolve, reject) => {
            reject(res);
        });
    };

    static all(list) {
        const result = [];
        let count = 0;
        function collectResult(res, resolve) {
            result.push(res);
            count++;
            if (count === list.length) {
                resolve(result);
            }
        };
        return new myPromise((resolve, reject) => {
            list.forEach(item => {
                if (item instanceof myPromise) {
                    item.then(res => {
                        collectResult(res, resolve);
                    }, err => {
                        reject(err);
                    });
                } else {
                    myPromise.resolve(item).then(res => {
                        collectResult(res, resolve);
                    });
                }
            });
        });
    };

    static race(list) {
        return myPromise((resolve, reject) => {
            list.forEach(item => {
                if (item instanceof myPromise) {
                    item.then(res => {
                        resolve(res);
                    }, err => {
                        reject(err);
                    });
                } else {
                    resolve(myPromise.resolve(item));
                }
            })
        });
    }
}