返回

从Promise规范到手写Promise,理解Promise的本质

前端

前言

Promise是JavaScript中用于处理异步编程的强大工具。它可以让你将异步任务队列化,按照顺序输出,同时用链式调用解决回调地狱的问题。Promise的出现极大地简化了异步编程,让代码更加清晰易读。

Promise规范

Promise规范定义了Promise对象的行为和用法。Promise对象有三种状态:

  • Pending: 初始状态,表示异步任务尚未完成。
  • Fulfilled: 成功状态,表示异步任务已成功完成。
  • Rejected: 失败状态,表示异步任务已失败。

Promise对象提供了两个方法:

  • resolve: 将Promise对象的状态从Pending变为Fulfilled。
  • reject: 将Promise对象的状态从Pending变为Rejected。

实现一个Promise

现在,让我们来实现一个简单的Promise。首先,我们需要创建一个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(value);
      });
    }
  };

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

  executor(resolve, reject);
}

然后,我们需要定义两个方法来处理Promise对象的状态:

Promise.prototype.then = function(onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    if (this.state === 'fulfilled') {
      setTimeout(() => {
        try {
          const value = onFulfilled(this.value);
          resolve(value);
        } catch (error) {
          reject(error);
        }
      }, 0);
    } else if (this.state === 'rejected') {
      setTimeout(() => {
        try {
          const reason = onRejected(this.reason);
          resolve(reason);
        } catch (error) {
          reject(error);
        }
      }, 0);
    } else {
      this.onFulfilledCallbacks.push(onFulfilled);
      this.onRejectedCallbacks.push(onRejected);
    }
  });
};

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

使用Promise

现在,我们就可以使用我们的Promise对象了。例如,我们可以使用它来获取JSON数据:

const promise = new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://example.com/api/data.json');
  xhr.onload = () => {
    if (xhr.status === 200) {
      resolve(JSON.parse(xhr.responseText));
    } else {
      reject(new Error('Error fetching data'));
    }
  };
  xhr.onerror = () => {
    reject(new Error('Error fetching data'));
  };
  xhr.send();
});

promise.then((data) => {
  console.log(data);
}).catch((error) => {
  console.error(error);
});

结语

以上就是Promise规范和如何实现一个Promise的简单介绍。希望你能通过本文对Promise有更深入的了解。如果你想了解更多关于Promise的知识,可以参考以下资源: