Promise 的三种状态:Pending, Fulfilled, Rejected
欢迎来到 Promise 世界!
大家好,今天我们要聊一聊 JavaScript 中的 Promise
。如果你觉得 Promise
很神秘,或者每次看到它都感觉像在看天书,别担心!我们今天会用轻松诙谐的方式,带你一步步了解 Promise
的三种状态:Pending、Fulfilled 和 Rejected。相信我,学完这篇讲座,你会对 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,因为我们还没有调用 resolve
或 reject
来改变它的状态。
小贴士:
Pending
状态是Promise
的初始状态,表示任务正在进行中。- 在
Pending
状态下,Promise
不会触发任何回调函数(如then
或catch
),因为它还没有完成。
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 状态下通过调用 resolve
或 reject
来改变状态。一旦进入了 Fulfilled 或 Rejected 状态,它就不会再发生变化。
小贴士:
Promise
是不可变的,一旦进入 Fulfilled 或 Rejected 状态,它将永远保持这个状态。- 你可以通过
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
的链式调用可以让多个异步操作按顺序执行。- 每个
then
或catch
都可以返回一个新的Promise
,从而形成一个连续的操作流。
总结
今天我们学习了 Promise
的三种状态:Pending、Fulfilled 和 Rejected。通过这些状态,我们可以更好地理解如何处理异步操作,并确保我们的代码在不同情况下都能正确执行。
- Pending:任务正在进行中,还没有完成。
- Fulfilled:任务顺利完成,可以通过
then
获取结果。 - Rejected:任务执行过程中出现了错误,可以通过
catch
捕获错误。
希望今天的讲座能让你对 Promise
有更清晰的认识。如果你还有疑问,欢迎随时提问!😊
参考资料
- MDN Web Docs: [Using Promises](MDN Web Docs 提供了详细的
Promise
文档,包括 API 说明和最佳实践。) - ECMAScript Specification: [Promise Objects](ECMAScript 规范定义了
Promise
的行为和实现细节。)
感谢大家的聆听,祝你编程愉快!