记录一下手动实现Promise

103 阅读1分钟

定义Promise状态

const PENDING = 'PENDING';
const SUCCESS = 'SUCCESS';
const REJECT = 'REJECT';

Promise 构造函数

function MyPromise(executor) {
    //初始化状态
    this.status = PENDING;
    const that = this;
    this.value = undefined;
    this.reason = undefined;
    
    // 存储异步回调方法
    this.onSuccessCallback = []; 
    this.onRejectCallback = [];
    function resolve(value) {
        if (value instanceof MyPromise) {
            return value.then(resolve, reject);
        }

        if (that.status === PENDING) {
            that.status = SUCCESS;
            that.value = value;
            that.onSuccessCallback.forEach((callback) => {
                callback(value);
            });
        }
    }

    function reject(value) {
        if (that.status === PENDING) {
            that.status = REJECT;
            that.reason = value;
            that.onRejectCallback.forEach((callback) => {
                callback(value);
            });
        }
    }
    executor(resolve, reject);
}

then 方法的实现

MyPromise.prototype.then = function (onFulfilled, onRejected) {
    // then 方法没有传回调方法时,实现值穿透
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (data) => data;
    onRejected =
        typeof onRejected === 'function'
            ? onRejected
            : (error) => {
                  throw error;
              };
    let promiseNext;
    if (this.status === SUCCESS) {
        return (promiseNext = new MyPromise((reslove, reject) => {
            setTimeout(() => {
                try {
                    let result = onFulfilled(this.value);
                    getResolveValue(promiseNext, result, reslove, reject);
                } catch (error) {
                    reject(error);
                }
            });
        }));
    } else if (this.status === REJECT) {
        return (promiseNext = new MyPromise((reslove, reject) => {
            setTimeout(() => {
                try {
                    let result = onRejected(this.reason);

                    getResolveValue(promiseNext, result, reslove, reject);
                } catch (error) {
                    reject(error);
                }
            });
        }));
    } else if (this.status === PENDING) {
    	// 保存then方法成功回调和失败回调(此处做了链式调用处理)
        return (promiseNext = new MyPromise((reslove, reject) => {
            this.onSuccessCallback.push((value) => {
                try {
                    let result = onFulfilled(value);
                    getResolveValue(promiseNext, result, reslove, reject);
                } catch (error) {
                    reject(error);
                }
            });
            this.onRejectCallback.push((reason) => {
                try {
                    let result = onRejected(reason);
                    getResolveValue(promiseNext, result, reslove, reject);
                } catch (error) {
                    reject(error);
                }
            });
        }));
    }
};

处理下一个Promise

function getResolveValue(promiseNext, result, reslove, reject) {
    if (result === promiseNext) {
        return reject(new TypeError('不可返回同一个promise对象'));
    }
    let mark; // 保证resolve、reject只执行一个
    if ((typeof result === 'object' && result != null) || typeof result === 'function') {
        try {
            let then = result.then;
            if (typeof then === 'function') {
                then.call(
                    result,
                    function (next) {
                        if (mark) return;
                        mark = true;
                        getResolveValue(promiseNext, next, reslove, reject);
                    },
                    function (err) {
                        if (mark) return;
                        mark = true;
                        reject(err);
                    }
                );
            } else {
                reslove(result);
            }
        } catch (error) {
            if (mark) return;
            reject(error);
        }
    } else {
        reslove(result);
    }
}

catch

MyPromise.prototype.catch = function (err) {
    return this.then(null, err);
};

reslove

MyPromise.reslove = function (value) {
    return new MyPromise((resolve, _) => {
        resolve(value);
    });
};

reject

MyPromise.reject = function (reason) {
    return new MyPromise((_, reject) => {
        reject(reason);
    });
};

all

MyPromise.all = function (arr) {
    if (!Array.isArray(arr)) {
        throw new TypeError('请传入一个数组');
    }

    return new MyPromise((resolve, reject) => {
        try {
            let resultArr = [];
            const len = arr.length;
            for (let i = 0; i < len; i++) {
                arr[i].then((data) => {
                    resultArr.push(data);
                    if (resultArr.length == len) {
                        resolve(resultArr);
                    }
                }, reject);
            }
        } catch (err) {
            reject(err);
        }
    });
};

from juejin.cn/post/692669…