手写 Promise 第一课:状态与控制

128 阅读2分钟

引言

在现代 JavaScript 开发中,异步编程是处理非阻塞操作的关键技术。Promise 对象提供了一种更加优雅的方式来处理异步操作,使得代码更加清晰和易于维护。在本篇博客中,我们将通过手写一个简单的 Promise 类来深入理解其内部机制,这是我们异步编程系列课程的第一课。

Promise 的核心概念

在深入代码之前,让我们先回顾一下 Promise 的核心概念:

  • PENDING:Promise 的初始状态,表示异步操作尚未完成。
  • FULFILLED:异步操作成功完成,Promise 将进入此状态。
  • REJECTED:异步操作失败,Promise 将进入此状态。

这三个状态是 Promise 规范中定义的,它们帮助我们管理和控制异步操作的生命周期。

手写 MyPromise 类

下面是我们第一节课的实践内容,我们将通过手写一个简单的 Promise 类来模拟 Promise 的行为:

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class MyPromise {
    constructor(executor) {
        this._state = PENDING; // 初始化状态为 pending
        this._value = undefined; // 用于存储异步操作的结果
        try {
            executor(this._resolve.bind(this), this._reject.bind(this));
        } catch (error) {
            this._reject(error); // 如果 executor 抛出错误,立即将状态设置为 rejected
        }
    }

    _changeState(newState, value) {
        if (this._state !== PENDING) {
            return; // 如果状态已经不是 pending,则不进行状态变更
        }
        this._state = newState; // 改变状态
        this._value = value; // 保存异步操作的结果
    }

    _resolve(data) {
        this._changeState(FULFILLED, data); // 异步操作成功,状态变为 fulfilled
        console.log('完成', data);
    }

    _reject(reason) {
        this._changeState(REJECTED, reason); // 异步操作失败,状态变为 rejected
        console.log('失败', reason);
    }
}

const pro = new MyPromise((resolve, reject) => {
    throw new Error('5555'); // 模拟异步操作失败
});
console.log(pro); // 输出 Promise 对象的状态和值

代码解析

  1. 构造函数:在构造函数中,我们初始化 Promise 对象的状态为 PENDING,并尝试执行传入的 executor 函数。如果 executor 抛出错误,我们立即调用 _reject 方法。
  2. _changeState 方法:这是一个私有方法,用于改变 Promise 的状态。它确保状态的改变是原子操作,并且只在状态为 PENDING 时才允许改变状态。
  3. _resolve 和 _reject 方法:这两个私有方法分别用于在异步操作成功或失败时调用。它们通过调用 _changeState 方法来改变状态,并记录相关的值。
  4. 测试 Promise:在示例中,我们创建了一个 MyPromise 实例,并在 executor 函数中抛出了一个错误。这将导致 Promise 状态变为 REJECTED,并打印出错误信息。

结论

通过这第一节课,我们学习了如何手写一个简单的 Promise 类,理解了 Promise 的三种状态以及如何通过代码来控制这些状态。这是我们异步编程系列课程的第一步,为后续更深入的学习打下了坚实的基础。

进一步阅读

希望这节课能够帮助你建立起对 Promise 的基本理解,为后续更深入的学习做好准备。