第 4 期 - 手写 Promise 的实现与优化
logoFRONTALK AI/10月27日 16:32/阅读原文

摘要

文章按照 Promise A +规范手写 Promise,详细阐述从基础构建到逐步优化的过程,包括 then 方法难点、实例方法 catch 和 finally 的实现,静态方法的手写,以及通过测试确保符合规范,还提及后续迭代器与生成器的学习预告。

一、Promise 的基本概念与规范

// 例如这里定义 Promise 的状态常量
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';

二、手写 Promise 的构造函数

class MyPromise {
    constructor(executor) {
        this.status = PROMISE_STATUS_PENDING;
        this.value = undefined;
        this.reason = undefined;
        const resolve = (value) => {
            if (this.status === PROMISE_STATUS_PENDING) {
                this.status = PROMISE_STATUS_FULFILLED;
                this.value = value;
                console.log("resolve 被调用");
            }
        };
        const reject = (reason) => {
            if (this.status === PROMISE_STATUS_PENDING) {
                this.status = PROMISE_STATUS_REJECTED;
                this.reason = reason;
                console.log("reject 被调用");
            }
        };
        executor(resolve, reject);
    }
}

三、then 方法的实现与优化

(一)初步实现

then(onFulfilled, onRejected) {
    this.onFulfilled = onFulfilled;
    this.onRejected = onRejected;
}

(二)异步执行顺序的处理

(三)then 方法的多次调用优化

(四)then 方法的链式调用优化

四、catch 方法的手写

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

五、finally 方法的手写

finally(onFinally) {
    this.then(() => {
        onFinally();
    }, () => {
        onFinally();
    });
}

六、Promise 静态方法的手写

(一)resolve 和 reject 方法

static resolve(value) {
    return new MyPromise((resolve) => resolve(value));
}
static reject(reason) {
    return new MyPromise((resolve, reject) => reject(reason));
}

(二)all 和 allSettled 方法

static all(promises) {
    return new MyPromise((resolve, reject) => {
        const values = [];
        promises.forEach(promise => {
            promise.then(res => {
                values.push(res);
                if (values.length === promises.length) {
                    resolve(values);
                }
            }, err => {
                reject(err);
            });
        });
    });
}
static allSettled(promises) {
    return new MyPromise((resolve) => {
        const results = [];
        promises.forEach(promise => {
            promise.then(res => {
                results.push({ status: PROMISE_STATUS_FULFILLED, value: res });
                if (results.length === promises.length) resolve(results);
            }, err => {
                results.push({ status: PROMISE_STATUS_REJECTED, value: err });
                if (results.length === promises.length) resolve(results);
            });
        });
    });
}

(三)race 和 any 方法

static race(promises) {
    return new MyPromise((resolve, reject) => {
        promises.forEach(promise => {
            promise.then(resolve, reject);
        });
    });
}
static any(promises) {
    const reasons = [];
    return new MyPromise((resolve, reject) => {
        promises.forEach(promise => {
            promise.then(resolve, err => {
                reasons.push(err);
                if (reasons.length === promises.length) {
                    reject(new AggregateError(reasons));
                }
            });
        });
    });
}

七、Promise A +规范测试

八、后续学习预告

 

扩展阅读

Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有