返回

Promise 原理分析与实现,打造更强大的异步编程体验

前端

Promise 的构成和需要实现的功能

按照 Promise/A+ 的标准,Promise 只需要实现 then 方法即可。至于如何实现,constructor 怎么写,并没有明确规定。因此,我们可以使用 ES5 或 ES6 来实现,只要注意以下几个重点即可:

    1. Promise 必须包含一个 then 方法,该方法接受两个参数:onFulfilledonRejected。当 Promise 处于已完成状态时,onFulfilled 将被调用;当 Promise 处于已拒绝状态时,onRejected 将被调用。
    1. Promise 必须包含一个 catch 方法,该方法接受一个参数:onRejected。当 Promise 处于已拒绝状态时,onRejected 将被调用。
    1. Promise 必须包含一个 finally 方法,该方法接受一个参数:onFinally。无论 Promise 处于已完成状态还是已拒绝状态,onFinally 都将被调用。

Promise 的实现

// 使用 ES5 实现 Promise
function Promise(executor) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

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

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

  executor(resolve, reject);
}

Promise.prototype.then = function(onFulfilled, onRejected) {
  if (this.state === 'pending') {
    this.onFulfilledCallbacks.push(onFulfilled);
    this.onRejectedCallbacks.push(onRejected);
  } else if (this.state === 'fulfilled') {
    onFulfilled(this.value);
  } else if (this.state === 'rejected') {
    onRejected(this.reason);
  }

  return this;
};

Promise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected);
};

Promise.prototype.finally = function(onFinally) {
  return this.then(
    (value) => {
      onFinally();
      return value;
    },
    (reason) => {
      onFinally();
      throw reason;
    }
  );
};

// 使用 ES6 实现 Promise
class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

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

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

    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    if (this.state === 'pending') {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    } else if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    } else if (this.state === 'rejected') {
      onRejected(this.reason);
    }

    return this;
  }

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

  finally(onFinally) {
    return this.then(
      (value) => {
        onFinally();
        return value;
      },
      (reason) => {
        onFinally();
        throw reason;
      }
    );
  }
}

Promise 的使用

Promise 的使用非常简单。首先,我们需要创建一个 Promise 对象。然后,我们可以使用 then 方法来指定当 Promise 完成时或拒绝时要执行的代码。

// 使用 Promise 实现异步请求
const request = new Promise((resolve, reject) => {
  // 发送异步请求
  setTimeout(() => {
    if (success) {
      resolve('请求成功');
    } else {
      reject('请求失败');
    }
  }, 1000);
});

request.then(
  (result) => {
    // 请求成功
    console.log(result);
  },
  (error) => {
    // 请求失败
    console.log(error);
  }
);

在上面的代码中,我们首先创建了一个 Promise 对象 request。然后,我们使用 then 方法指定当 Promise 完成时或拒绝时要执行的代码。当 Promise 完成时,then 方法的第一个参数 result 将包含请求的结果。当 Promise 拒绝时,then 方法的第二个参数 error 将包含请求的错误信息。

总结

Promise 是 JavaScript 中非常重要的概念,它允许我们以一种更优雅的方式处理异步操作。通过了解 Promise 的原理和实现,我们可以更好地使用 Promise 来编写更健壮的代码。