返回

剖析ES6 Promise,轻松掌握异步编程

前端

序章:JavaScript异步编程的痛点

在JavaScript中,异步编程是处理IO操作的常见方式,例如网络请求、文件读取、定时器等。传统的异步编程通常采用回调函数的形式,这种方式虽然简单易懂,但当多个异步操作嵌套时,代码很容易变得混乱且难以维护。

一、PromiseA+规范:Promise的基石

为了解决回调函数的痛点,ES6引入了Promise特性,并制定了PromiseA+规范。PromiseA+规范为Promise的实现提供了统一的标准,确保了不同库和框架之间的一致性。

二、Promise的原理与用法

Promise本质上是一个对象,它代表一个异步操作的结果,并提供了then方法来处理这个结果。Promise有三种状态:Pending(等待)、Fulfilled(已完成)和Rejected(已拒绝)。

  1. Pending :初始状态,表示异步操作尚未完成。
  2. Fulfilled :异步操作成功完成,并产生了一个结果值。
  3. Rejected :异步操作失败,并产生一个错误值。

then方法接受两个参数:onFulfilled和onRejected。当Promise的状态变为Fulfilled时,调用onFulfilled并传递结果值;当Promise的状态变为Rejected时,调用onRejected并传递错误值。

三、手撸简易版本Promise

为了加深对Promise的理解,我们不妨动手撸一个简易版本的Promise。

// 定义Promise类
class Promise {
  constructor(executor) {
    this.status = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    // 执行executor函数
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }

  // 改变Promise状态为Fulfilled
  resolve(value) {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach(callback => callback(this.value));
    }
  }

  // 改变Promise状态为Rejected
  reject(reason) {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach(callback => callback(this.reason));
    }
  }

  // 注册fulfilled回调函数
  then(onFulfilled, onRejected) {
    if (this.status === 'fulfilled') {
      onFulfilled(this.value);
    } else if (this.status === 'rejected') {
      onRejected(this.reason);
    } else {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    }

    return this;
  }
}

结语

通过剖析ES6 Promise,我们深入了解了Promise的原理和用法。手撸简易版本Promise的练习更是让我们对Promise的内部机制有了更深刻的理解。掌握Promise,你将能够更轻松地驾驭JavaScript异步编程,编写更加优雅高效的代码。