请实现一个符合Promise/A+规范的Promise

在JavaScript中,Promise 是一种代表异步操作最终完成或失败的对象。一个 Promise 处于以下状态之一:

  • pending:初始状态,既不是成功,也不是失败状态。
  • fulfilled:意味着操作成功完成。
  • rejected:意味着操作失败。

下面是一个简单的 Promise 实现,符合 Promise/A+ 规范:

function Promise(executor) {
    let self = this;
    self.status = 'pending';
    self.value = undefined;
    self.reason = undefined;
    self.onFulfilledCallbacks = [];
    self.onRejectedCallbacks = [];

    function resolve(value) {
        if (self.status === 'pending') {
            self.status = 'fulfilled';
            self.value = value;
            self.onFulfilledCallbacks.forEach(fn => fn());
        }
    }

    function reject(reason) {
        if (self.status === 'pending') {
            self.status = 'rejected';
            self.reason = reason;
            self.onRejectedCallbacks.forEach(fn => fn());
        }
    }

    try {
        executor(resolve, reject);
    } catch (err) {
        reject(err);
    }
}

Promise.prototype.then = function(onFulfilled, onRejected) {
    let self = this;
    let promise2 = new Promise((resolve, reject) => {
        if (self.status === 'fulfilled') {
            setTimeout(() => {
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0);
        }
        if (self.status === 'rejected') {
            setTimeout(() => {
                try {
                    let x = onRejected(self.reason);
                    resolvePromise(promise2, x, resolve, reject);
                } catch (e) {
                    reject(e);
                }
            }, 0);
        }
        if (self.status === 'pending') {
            self.onFulfilledCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(self.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            });
            self.onRejectedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onRejected(self.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            });
        }
    });
    return promise2;
};

function resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise'));
    }
    let called = false;
    if ((typeof x === 'object' && x !== null) || typeof x === 'function') {
        try {
            let then = x.then;
            if (typeof then === 'function') {
                then.call(x, y => {
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject);
                }, r => {
                    if (called) return;
                    called = true;
                    reject(r);
                });
                return;
            }
        } catch (e) {
            if (called) return;
            called = true;
            reject(e);
            return;
        }
    }
    resolve(x);
}

注意:这个实现是简化的,并不包含所有的错误处理和边界情况。在生产环境中,建议使用原生的 Promise 或成熟的第三方库(如 Bluebird、Q 等)。

posted @ 2024-12-21 09:11  王铁柱6  阅读(12)  评论(0)    收藏  举报