Promise的状态:Pending, Fulfilled, Rejected

Promise 的三种状态:Pending, Fulfilled, Rejected

欢迎来到 Promise 世界!

大家好,今天我们要聊一聊 JavaScript 中的 Promise。如果你觉得 Promise 很神秘,或者每次看到它都感觉像在看天书,别担心!我们今天会用轻松诙谐的方式,带你一步步了解 Promise 的三种状态:PendingFulfilledRejected。相信我,学完这篇讲座,你会对 Promise 有全新的认识!

什么是 Promise?

首先,Promise 是 JavaScript 中用于处理异步操作的对象。你可以把它想象成一个“承诺”——你告诉别人你会做某件事,但这件事可能需要一些时间才能完成。在这段时间里,这个“承诺”会有不同的状态。

  • Pending(待定):表示任务还没有完成,还在进行中。
  • Fulfilled(已成功):表示任务已经顺利完成。
  • Rejected(已失败):表示任务执行过程中出现了错误或问题。

接下来,我们就来详细看看这三种状态是如何工作的。


1. Pending 状态:等待中的承诺

当一个 Promise 被创建时,它的初始状态是 Pending。这意味着任务还没有开始,或者已经开始但还没有完成。你可以把它想象成你在等外卖,订单刚下单,骑手还没送到,你就处于“等待中”的状态。

const myPromise = new Promise((resolve, reject) => {
  // 这里的代码会在一段时间后执行
  console.log("正在处理中...");
});

console.log(myPromise);  // 输出: Promise { <pending> }

在这个例子中,myPromise 刚被创建时,它的状态是 Pending,因为我们还没有调用 resolvereject 来改变它的状态。

小贴士:

  • Pending 状态是 Promise 的初始状态,表示任务正在进行中。
  • Pending 状态下,Promise 不会触发任何回调函数(如 thencatch),因为它还没有完成。

2. Fulfilled 状态:成功的承诺

当任务顺利完成时,Promise 会进入 Fulfilled 状态。你可以把它想象成外卖终于送到了,而且一切都很好,没有出任何问题。这时,Promise 会调用 resolve 函数,并传递一个成功的值。

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("任务完成了!");
    resolve("成功了!");
  }, 2000);
});

myPromise.then((result) => {
  console.log(result);  // 输出: 成功了!
});

在这个例子中,setTimeout 模拟了一个耗时 2 秒的任务。当任务完成后,resolve 被调用,Promise 进入 Fulfilled 状态,并通过 then 回调函数输出结果。

小贴士:

  • Fulfilled 状态表示任务已经成功完成。
  • 一旦 Promise 进入 Fulfilled 状态,它将永远保持这个状态,不会再发生变化。
  • 你可以通过 then 方法来处理 Fulfilled 状态下的结果。

3. Rejected 状态:失败的承诺

有时候,事情并不会总是如愿以偿。如果任务执行过程中出现了错误,Promise 会进入 Rejected 状态。你可以把它想象成外卖小哥在路上遇到了交通堵塞,导致订单无法按时送达。这时,Promise 会调用 reject 函数,并传递一个错误信息。

const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("任务失败了!");
    reject(new Error("出了问题!"));
  }, 2000);
});

myPromise.catch((error) => {
  console.error(error.message);  // 输出: 出了问题!
});

在这个例子中,setTimeout 模拟了一个失败的任务。当任务失败时,reject 被调用,Promise 进入 Rejected 状态,并通过 catch 回调函数捕获并处理错误。

小贴士:

  • Rejected 状态表示任务执行过程中出现了错误。
  • 一旦 Promise 进入 Rejected 状态,它将永远保持这个状态,不会再发生变化。
  • 你可以通过 catch 方法来处理 Rejected 状态下的错误。

Promise 的状态转换

现在我们知道了 Promise 有三种状态,那么这些状态之间是如何转换的呢?下面是一个简单的状态转换图:

当前状态 调用方法 新状态
Pending resolve() Fulfilled
Pending reject() Rejected
Fulfilled 保持不变
Rejected 保持不变

从表中可以看出,Promise 只能在 Pending 状态下通过调用 resolvereject 来改变状态。一旦进入了 FulfilledRejected 状态,它就不会再发生变化。

小贴士:

  • Promise 是不可变的,一旦进入 FulfilledRejected 状态,它将永远保持这个状态。
  • 你可以通过 then 处理 Fulfilled 状态,通过 catch 处理 Rejected 状态。

实战演练:链式调用

Promise 的一大优势是可以进行链式调用。这意味着你可以在一个 Promise 完成后,继续返回另一个 Promise,形成一个连续的操作流。让我们来看一个实际的例子:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const data = { name: "Alice", age: 25 };
      resolve(data);
    }, 1000);
  });
};

const processUser = (user) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (user.age >= 18) {
        resolve(`${user.name} 是成年人`);
      } else {
        reject(new Error(`${user.name} 是未成年人`));
      }
    }, 1000);
  });
};

fetchData()
  .then(processUser)
  .then((message) => {
    console.log(message);  // 输出: Alice 是成年人
  })
  .catch((error) => {
    console.error(error.message);  // 如果用户是未成年人,这里会捕获错误
  });

在这个例子中,fetchData 返回一个 Promise,它会在 1 秒后解析为用户数据。然后,我们使用 then 链接 processUser,后者会根据用户的年龄返回不同的结果。如果用户是成年人,程序会输出相应的消息;如果用户是未成年人,程序会抛出错误并被捕获。

小贴士:

  • Promise 的链式调用可以让多个异步操作按顺序执行。
  • 每个 thencatch 都可以返回一个新的 Promise,从而形成一个连续的操作流。

总结

今天我们学习了 Promise 的三种状态:PendingFulfilledRejected。通过这些状态,我们可以更好地理解如何处理异步操作,并确保我们的代码在不同情况下都能正确执行。

  • Pending:任务正在进行中,还没有完成。
  • Fulfilled:任务顺利完成,可以通过 then 获取结果。
  • Rejected:任务执行过程中出现了错误,可以通过 catch 捕获错误。

希望今天的讲座能让你对 Promise 有更清晰的认识。如果你还有疑问,欢迎随时提问!😊


参考资料

  • MDN Web Docs: [Using Promises](MDN Web Docs 提供了详细的 Promise 文档,包括 API 说明和最佳实践。)
  • ECMAScript Specification: [Promise Objects](ECMAScript 规范定义了 Promise 的行为和实现细节。)

感谢大家的聆听,祝你编程愉快!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注