JavaScript 异步编程:Promise¶
概述¶
在 JavaScript 中,异步编程是处理耗时操作(如网络请求、文件读写等)的关键。传统的回调函数虽然可以实现异步操作,但随着代码复杂度的增加,回调地狱(Callback Hell)问题变得难以管理。为了解决这个问题,ES6 引入了 Promise
,它提供了一种更优雅的方式来处理异步操作。
什么是 Promise?¶
Promise
是一个表示异步操作最终完成或失败的对象。它有三种状态:
- Pending(进行中):初始状态,既不是成功,也不是失败。
- Fulfilled(已成功):操作成功完成。
- Rejected(已失败):操作失败。
Promise
的状态一旦改变,就不会再变。这意味着一个 Promise
只能从 Pending
变为 Fulfilled
或 Rejected
,且不可逆。
创建 Promise¶
你可以使用 new Promise()
构造函数来创建一个 Promise
对象。构造函数接受一个函数作为参数,这个函数有两个参数:resolve
和 reject
,它们分别是成功和失败时的回调函数。
const myPromise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true; // 模拟操作成功或失败
if (success) {
resolve("操作成功!");
} else {
reject("操作失败!");
}
}, 1000);
});
在上面的代码中,setTimeout
模拟了一个异步操作。如果操作成功,调用 resolve
并传递结果;如果失败,调用 reject
并传递错误信息。
处理 Promise¶
使用 .then()
和 .catch()
¶
Promise
提供了 .then()
和 .catch()
方法来处理成功和失败的情况。
myPromise
.then((result) => {
console.log(result); // 输出: 操作成功!
})
.catch((error) => {
console.error(error); // 输出: 操作失败!
});
.then()
方法接收一个回调函数,当Promise
状态变为Fulfilled
时调用。.catch()
方法接收一个回调函数,当Promise
状态变为Rejected
时调用。
使用 .finally()
¶
.finally()
方法无论 Promise
成功还是失败都会执行,通常用于清理操作。
myPromise
.then((result) => {
console.log(result);
})
.catch((error) => {
console.error(error);
})
.finally(() => {
console.log("操作完成!");
});
链式调用¶
Promise
支持链式调用,这意味着你可以在一个 .then()
中返回一个新的 Promise
,并在下一个 .then()
中处理它。
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("数据获取成功!");
}, 1000);
});
};
fetchData()
.then((data) => {
console.log(data); // 输出: 数据获取成功!
return "处理数据...";
})
.then((processedData) => {
console.log(processedData); // 输出: 处理数据...
})
.catch((error) => {
console.error(error);
});
并行处理多个 Promise¶
你可以使用 Promise.all()
方法来并行处理多个 Promise
,并在所有 Promise
都成功时返回结果数组。
const promise1 = Promise.resolve("第一个操作成功!");
const promise2 = new Promise((resolve) => {
setTimeout(() => {
resolve("第二个操作成功!");
}, 1000);
});
Promise.all([promise1, promise2])
.then((results) => {
console.log(results); // 输出: ["第一个操作成功!", "第二个操作成功!"]
})
.catch((error) => {
console.error(error);
});
如果其中一个 Promise
失败,Promise.all()
会立即返回失败的结果。
练习题¶
练习 1:基本 Promise 使用¶
编写一个 Promise
,模拟一个异步操作,操作成功时返回 "Hello, World!",失败时返回 "Error!"。使用 .then()
和 .catch()
处理结果。
练习 2:链式调用¶
编写一个 Promise
链,模拟以下操作: 1. 获取用户数据(模拟异步操作,返回 "用户数据获取成功!")。 2. 处理用户数据(返回 "用户数据处理完成!")。 3. 保存用户数据(返回 "用户数据保存成功!")。
练习 3:并行处理¶
编写三个 Promise
,分别模拟三个异步操作,每个操作耗时不同(1秒、2秒、3秒)。使用 Promise.all()
并行处理这三个 Promise
,并在所有操作完成后输出结果。
总结¶
Promise
是 JavaScript 中处理异步操作的一种方式,它有三种状态:Pending
、Fulfilled
和Rejected
。- 使用
.then()
处理成功的结果,使用.catch()
处理失败的结果,使用.finally()
执行清理操作。 Promise
支持链式调用,可以在一个.then()
中返回新的Promise
。- 使用
Promise.all()
可以并行处理多个Promise
,并在所有Promise
都成功时返回结果数组。
通过掌握 Promise
,你可以更优雅地处理 JavaScript 中的异步操作,避免回调地狱,并编写出更清晰、更易维护的代码。