手写 Promise (完整的)

197 阅读1分钟
class MyPromise {
    constructor(executor) {
        this.state = 'pending';
        this.id = id++
        this.value = undefined;
        this.error = undefined;
        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = (value) => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
                setTimeout(() => {
                    this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
                });
            }
        };

        const reject = (error) => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.error = error;
                this.onRejectedCallbacks.forEach((callback) => callback(this.error));
            }
        };

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

    then(onFulfilled, onRejected) {
        return new MyPromise((resolve, reject) => {
            const onFulfilledCallback = (value) => {
                try {
                    if (typeof onFulfilled === 'function') {
                        const result = onFulfilled(value);
                        if (result instanceof MyPromise) {
                            // 如果返回值是Promise对象,等待其状态改变后再执行下一步
                            result.then(resolve, reject);
                        } else {
                            resolve(result);
                        }
                    } else {
                        resolve(value);
                    }
                } catch (error) {
                    reject(error);
                }
            };

            const onRejectedCallback = (error) => {
                try {
                    if (typeof onRejected === 'function') {
                        const result = onRejected(error);
                        if (result instanceof MyPromise) {
                            // 如果返回值是Promise对象,等待其状态改变后再执行下一步
                            result.then(resolve, reject);
                        } else {
                            resolve(result);
                        }
                    } else {
                        reject(error);
                    }
                } catch (error) {
                    reject(error);
                }
            };

            if (this.state === 'fulfilled') {
                setTimeout(() => {
                    onFulfilledCallback(this.value);
                });
            } else if (this.state === 'rejected') {
                setTimeout(() => {
                    onRejectedCallback(this.error);
                });
            } else {
                this.onFulfilledCallbacks.push(onFulfilledCallback);
                this.onRejectedCallbacks.push(onRejectedCallback);
            }
        });
    }

    catch (onRejected) {
        return this.then(undefined, onRejected);
    }

    static all(promises) {
        return new MyPromise((resolve, reject) => {
            const results = [];
            let completedCount = 0;

            for (let i = 0; i < promises.length; i++) {
                promises[i].then((value) => {
                    results[i] = value;
                    completedCount++;

                    if (completedCount === promises.length) {
                        resolve(results);
                    }
                }).catch(reject);
            }
        });
    }

    static race(promises) {
        return new MyPromise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(resolve).catch(reject);
            }
        });
    }
}