返回

让你的代码焕发生机:从头理解 Promise 手写过程!

前端

作为一名 00 后程序员,我无法错过手写 Promise 的挑战。Promise 作为 Javascript 中的异步编程利器,以其优雅简洁的语法征服了无数开发者的心。但是,真正理解 Promise 的本质并能手写实现它,才是进阶为资深程序员的标志。

从头理解 Promise

在动手编码之前,我们先来理清 Promise 的基本概念。Promise 本质上是一个对象,它代表了一个异步操作的最终完成或失败状态。我们可以通过 Promise 来处理异步操作的结果,并在操作完成后执行相应的回调函数。

Promise 提供了三个主要方法:

  • then():用于处理 Promise 的成功结果。
  • catch():用于处理 Promise 的失败结果。
  • finally():无论 Promise 成功还是失败,都会执行的操作。

手写 Promise 的步骤

现在,让我们来一步一步地手写实现一个 Promise:

  1. 定义一个 Promise 构造函数:
function Promise(executor) {
  // executor 是一个函数,它接受两个参数:resolve 和 reject
  // resolve 用于将 Promise 的状态设置为成功,并传入成功结果
  // reject 用于将 Promise 的状态设置为失败,并传入失败原因
  // 将 Promise 的状态初始化为 pending
  this.state = 'pending';
  // 将 Promise 的结果初始化为 undefined
  this.result = undefined;
  // 将 Promise 的回调函数列表初始化为空数组
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  // 立即执行 executor 函数
  try {
    executor(resolve.bind(this), reject.bind(this));
  } catch (error) {
    // 如果 executor 函数抛出异常,则将 Promise 的状态设置为失败,并传入异常信息
    reject(error);
  }
}
  1. 定义 then() 方法:
Promise.prototype.then = function(onFulfilled, onRejected) {
  // 如果 onFulfilled 不是函数,则将其设置为一个默认函数,该函数直接返回结果
  onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(result) { return result; };
  // 如果 onRejected 不是函数,则将其设置为一个默认函数,该函数直接抛出异常
  onRejected = typeof onRejected === 'function' ? onRejected : function(error) { throw error; };

  // 将 onFulfilled 和 onRejected 回调函数添加到相应的回调函数列表中
  this.onFulfilledCallbacks.push(onFulfilled);
  this.onRejectedCallbacks.push(onRejected);

  // 如果 Promise 的状态已经变更为成功,则立即执行 onFulfilled 回调函数
  if (this.state === 'fulfilled') {
    onFulfilled(this.result);
  }
  // 如果 Promise 的状态已经变更为失败,则立即执行 onRejected 回调函数
  else if (this.state === 'rejected') {
    onRejected(this.result);
  }

  // 返回一个新的 Promise,该 Promise 的状态取决于当前 Promise 的状态和回调函数的执行结果
  return new Promise(function(resolve, reject) {
    // 如果当前 Promise 的状态变更为成功,则执行 onFulfilled 回调函数,并将结果传递给 resolve
    this.onFulfilledCallbacks.push(function(result) {
      try {
        // 执行 onFulfilled 回调函数,并将结果传递给 resolve
        var result = onFulfilled(result);
        // 将新 Promise 的状态设置为成功,并传入结果
        resolve(result);
      } catch (error) {
        // 如果 onFulfilled 回调函数抛出异常,则将新 Promise 的状态设置为失败,并传入异常信息
        reject(error);
      }
    });

    // 如果当前 Promise 的状态变更为失败,则执行 onRejected 回调函数,并将结果传递给 reject
    this.onRejectedCallbacks.push(function(error) {
      try {
        // 执行 onRejected 回调函数,并将结果传递给 reject
        var result = onRejected(error);
        // 将新 Promise 的状态设置为成功,并传入结果
        resolve(result);
      } catch (error) {
        // 如果 onRejected 回调函数抛出异常,则将新 Promise 的状态设置为失败,并传入异常信息
        reject(error);
      }
    });
  });
};
  1. 定义 catch() 方法:
Promise.prototype.catch = function(onRejected) {
  // 将 onRejected 回调函数添加到 onRejected 回调函数列表中
  this.onRejectedCallbacks.push(onRejected);

  // 返回一个新的 Promise,该 Promise 的状态取决于当前 Promise 的状态和回调函数的执行结果
  return new Promise(function(resolve, reject) {
    // 如果当前 Promise 的状态变更为成功,则执行 resolve,并将结果传递给新 Promise
    this.onFulfilledCallbacks.push(function(result) {
      resolve(result);
    });

    // 如果当前 Promise 的状态变更为失败,则执行 onRejected 回调函数,并将结果传递给新 Promise
    this.onRejectedCallbacks.push(function(error) {
      try {
        // 执行 onRejected 回调函数,并将结果传递给 resolve
        var result = onRejected(error);
        resolve(result);
      } catch (error) {
        // 如果 onRejected 回调函数抛出异常,则将新 Promise 的状态设置为失败,并传入异常信息
        reject(error);
      }
    });
  });
};

**手写 Promise 的优势** 

手写 Promise 有以下优势:

* 加深对 Promise 的理解:通过手写 Promise,可以更好地理解 Promise 的内部实现机制和工作原理。
* 提高编码能力:手写 Promise 可以锻炼编码能力,提高对 Javascript 的掌握程度。
* 增强代码的可读性和可维护性:手写 Promise 可以使代码更加清晰易懂,便于维护和扩展。

**结语** 

手写 Promise 是一个挑战,但也是一个学习和成长的机会。通过手写 Promise,我们可以加深对 Promise 的理解,提高编码能力,增强代码的可读性和可维护性。如果你想成为一名优秀的 Javascript 开发者,那么手写 Promise 是必经之路。