3

昨天看了Peter谭金杰 大佬分享的文章从零手写逐步实现Promise A+标准的所有方法 感谢大佬的分享 自己尝试着实现了一个乞丐版

核心思路1:
then方法的实现,then方法的参数作为回调函数入栈
catch方法的实现,catch的参数作为回调函数入栈

核心思路2:
链式调用的实现只需要返回this,Jquery,Zepto源码常用

完整代码如下:

class HackPromise {
    constructor(fn) {
        this.status = this.PROMISE_STATUS.PENDING;
        this.onFulfilledStack = [];
        this.onRejectedStack = [];
        fn(this.onResolve, this.onReject);
    }

    PROMISE_STATUS = Object.freeze(
        {
            PENDING: 'pending',
            FULFILLED: 'fulfilled',
            REJECTED: 'rejected'
        }
    );

    static resolve = value => new HackPromise(resolve => resolve(value));
    static reject = error => new HackPromise((resolve, reject) => reject(error));
    static all = promiseArr => {
        const promiseArrLength = promiseArr.length;
        const promiseResArr = [];
        let promiseResArrEnd = false;

        return new HackPromise((resolve, reject) => {
            for (let i = 0; i < promiseArrLength; i++) {
                promiseArr[i]
                    .then(res => {
                        if (promiseResArrEnd) {
                            return;
                        }

                        promiseResArr[i] = res;

                        if (promiseResArr.filter(promiseRes => promiseRes).length === promiseArrLength) {
                            promiseResArrEnd = true;
                            resolve(promiseResArr);
                        }
                    })
                    .catch(e => {
                        if (promiseResArrEnd) {
                            return;
                        }

                        promiseResArrEnd = true;
                        reject(e);
                    });
            }
        });
    };
    static race = promiseArr => {
        let promiseResArrEnd = false;

        return new HackPromise((resolve, reject) => {
            for (let i = 0; i < promiseArr.length; i++) {
                promiseArr[i]
                    .then(res => {
                        if (promiseResArrEnd) {
                            return;
                        }

                        promiseResArrEnd = true;
                        resolve(res);
                    })
                    .catch(e => {
                        if (promiseResArrEnd) {
                            return;
                        }

                        promiseResArrEnd = true;
                        reject(e);
                    });
            }
        });
    };

    onResolve = value => {
        if (this.status === this.PROMISE_STATUS.PENDING) {
            setTimeout(() => {
                this.status = this.PROMISE_STATUS.FULFILLED;
                this.onFulfilledStack.forEach(cb => cb(value));
            }, 0);
        }

        return this;
    };

    onReject = error => {
        if (this.status === this.PROMISE_STATUS.PENDING) {
            setTimeout(() => {
                this.status = this.PROMISE_STATUS.REJECTED;
                this.onRejectedStack.forEach(cb => cb(error));
            }, 0);
        }

        return this;
    };

    then = onFulfilled => {
        if (this.status === this.PROMISE_STATUS.PENDING) {
            this.onFulfilledStack.push(onFulfilled);
        }

        return this;
    };

    catch = onRejected => {
        if (this.status === this.PROMISE_STATUS.PENDING) {
            this.onRejectedStack.push(onRejected);
        }

        return this;
    };
}

十月安徒生
108 声望2 粉丝