chunhuile / common

0 stars 0 forks source link

简写版promise #1

Open chunhuile opened 3 months ago

chunhuile commented 3 months ago

`


  class MyPromise {

       constructor(executor) {

        // 初始状态为 pending,结果值和拒因值为 undefined
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;

      // 成功与失败回调存储的数组(处理异步)
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];

        // 定义 resolve 方法
        const resolve = (value) => {
            // 只有当状态是 pending 时,才能转成 fulfilled
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;

                // 执行所有成功的回调
                this.onFulfilledCallbacks.forEach((callback) => callback());
            }
        };

        // 定义 reject 方法
        const reject = (reason) => {
            // 只有当状态是 pending 时,才能转成 rejected
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;

                // 执行所有失败的回调
                this.onRejectedCallbacks.forEach((callback) => callback());
            }
        };

        // 立即执行 executor,捕获可能发生的异常
        try {
            executor(resolve, reject);
        } catch (err) {
            reject(err); // 如果执行过程中出错,直接 reject
        }
    }

    // then 方法
    then(onFulfilled, onRejected) {
        // 处理默认值(如果没有传入对应回调函数)
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
        onRejected = typeof onRejected === 'function' ? onRejected : (err) => { throw err; };

        // 支持链式调用,因此返回一个新的 Promise
        return new MyPromise((resolve, reject) => {
            if (this.state === 'fulfilled') {
                // 异步执行
                setTimeout(() => {
                    try {
                        const result = onFulfilled(this.value);
                        resolve(result);
                    } catch (err) {
                        reject(err);
                    }
                }, 0);
            }

            if (this.state === 'rejected') {
                // 异步执行
                setTimeout(() => {
                    try {
                        const result = onRejected(this.reason);
                        reject(result);
                    } catch (err) {
                        reject(err);
                    }
                }, 0);
            }

            if (this.state === 'pending') {
                // 如果状态是 pending,则将回调存入队列,在状态变更时再调用
                this.onFulfilledCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            const result = onFulfilled(this.value);
                            resolve(result);
                        } catch (err) {
                            reject(err);
                        }
                    }, 0);
                });

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

`

chunhuile commented 3 months ago

测试上面的案例的代码:

let p = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('Success!');
    }, 1000);
});

p.then((value) => {
    console.log(value); // 输出 'Success!'
    return 'Next step';
}).then((nextValue) => {
    console.log(nextValue); // 输出 'Next step'
});
chunhuile commented 3 months ago

关键点解析 状态管理

pending:初始状态,表示未完成。 fulfilled:成功状态。 rejected:失败状态。 resolve 和 reject 方法会改变 Promise 的状态,一旦状态改变,就不能再次修改。 回调队列

在 pending 状态时,将 then 的回调函数存入队列,等到状态变为 fulfilled 或 rejected 时,再执行对应的回调。 then 方法

then 方法返回一个新的 Promise,支持链式调用。 内部使用 setTimeout 来模拟微任务,以确保回调是异步执行的。 异常处理

try/catch 块用于捕获执行回调时的异常,并且在异常时调用 reject。