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 中的异步操作,避免回调地狱,并编写出更清晰、更易维护的代码。