Skip to content

手写promise

js
class MyPromise {
    // 定义三种状态
    static PENDING = 'pending';
    static FULFILLED = 'fulfilled';
    static REJECTED = 'rejected';

    constructor(executor) {
        // 初始状态为pending
        this.status = MyPromise.PENDING;
        // 存储成功的值
        this.value = null;
        // 存储失败的原因
        this.reason = null;
        // 存储成功的回调函数队列
        this.onFulfilledCallbacks = [];
        // 存储失败的回调函数队列
        this.onRejectedCallbacks = [];

        // 成功回调
        const resolve = (value) => {
            // 只有pending状态才能转换
            if (this.status === MyPromise.PENDING) {
                // 异步执行,模拟浏览器微任务
                queueMicrotask(() => {
                    this.status = MyPromise.FULFILLED;
                    this.value = value;
                    // 执行所有成功回调
                    this.onFulfilledCallbacks.forEach(callback => callback(value));
                });
            }
        };

        // 失败回调
        const reject = (reason) => {
            // 只有pending状态才能转换
            if (this.status === MyPromise.PENDING) {
                // 异步执行,模拟浏览器微任务
                queueMicrotask(() => {
                    this.status = MyPromise.REJECTED;
                    this.reason = reason;
                    // 执行所有失败回调
                    this.onRejectedCallbacks.forEach(callback => callback(reason));
                });
            }
        };

        try {
            // 执行 executor 函数
            executor(resolve, reject);
        } catch (error) {
            // 若执行过程中出错,直接reject
            reject(error);
        }
    }

    // then方法实现链式调用
    then(onFulfilled, onRejected) {
        // 处理onFulfilled和onRejected不是函数的情况
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => {
            throw reason;
        };

        // 返回新的Promise以支持链式调用
        return new MyPromise((resolve, reject) => {
            // 处理当前状态为fulfilled的情况
            if (this.status === MyPromise.FULFILLED) {
                queueMicrotask(() => {
                    try {
                        // 执行成功回调并获取返回值
                        const result = onFulfilled(this.value);
                        // 解析返回值,如果是Promise则等待其完成
                        this.resolvePromise(result, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }

            // 处理当前状态为rejected的情况
            if (this.status === MyPromise.REJECTED) {
                queueMicrotask(() => {
                    try {
                        // 执行失败回调并获取返回值
                        const result = onRejected(this.reason);
                        // 解析返回值
                        this.resolvePromise(result, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }

            // 处理当前状态为pending的情况
            if (this.status === MyPromise.PENDING) {
                // 将回调存入队列,等待状态变更
                this.onFulfilledCallbacks.push(() => {
                    try {
                        const result = onFulfilled(this.value);
                        this.resolvePromise(result, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });

                this.onRejectedCallbacks.push(() => {
                    try {
                        const result = onRejected(this.reason);
                        this.resolvePromise(result, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }
        });
    }

    // 解析then方法返回值
    resolvePromise(result, resolve, reject) {
        // 防止循环引用
        if (result === this) {
            return reject(new TypeError('Chaining cycle detected for promise'));
        }

        // 如果返回值是Promise
        if (result instanceof MyPromise) {
            result.then(resolve, reject);
        } else {
            // 否则直接resolve
            resolve(result);
        }
    }

    // catch方法,用于捕获错误
    catch(onRejected) {
        return this.then(null, onRejected);
    }

    // finally方法,无论成功失败都会执行
    finally(callback) {
        return this.then(value => MyPromise.resolve(callback()).then(() => value), reason => MyPromise.resolve(callback()).then(() => {
            throw reason;
        }));
    }

    // 静态resolve方法
    static resolve(value) {
        if (value instanceof MyPromise) {
            return value;
        }
        return new MyPromise(resolve => resolve(value));
    }

    // 静态reject方法
    static reject(reason) {
        return new MyPromise((resolve, reject) => reject(reason));
    }
}


// 测试代码
console.log('开始测试');

// 基本用法测试
const promise = new MyPromise((resolve, reject) => {
    console.log('执行executor');
    setTimeout(() => {
        resolve('成功的值');
        // 测试失败情况
        // reject(new Error('失败原因'));
    }, 1000);
});

promise
    .then(value => {
        console.log('第一个then:', value);
        return '第一个then返回值';
    })
    .then(value => {
        console.log('第二个then:', value);
        return new MyPromise(resolve => {
            setTimeout(() => resolve('第二个then返回的Promise'), 1000);
        });
    })
    .then(value => {
        console.log('第三个then:', value);
        // 测试错误抛出
        // throw new Error('手动抛出错误');
        return '完成';
    })
    .catch(error => {
        console.log('捕获错误:', error.message);
    })
    .finally(() => {
        console.log('finally执行');
    });

console.log('测试结束');