1. 基本的 Promise + .then() / .catch()
示例:Promise 基本用法
// 模拟一个异步操作的函数,返回一个 Promise
function fetchData(delay, result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) { // 模拟成功和失败
resolve(result);
} else {
reject("请求失败");
}
}, delay);
});
}
// 使用 .then() 和 .catch() 处理 Promise
fetchData(1000, "数据1")
.then((data) => {
console.log("成功获取数据:", data);
return fetchData(1000, "数据2"); // 返回一个新的 Promise
})
.then((data) => {
console.log("成功获取数据:", data);
return fetchData(1000, "数据3");
})
.then((data) => {
console.log("成功获取数据:", data);
})
.catch((err) => {
console.error("操作失败:", err);
});
解释:
.then()用于处理成功的结果(即resolve()的返回值)。.catch()用于捕获并处理异常(即reject()的错误)。
2. Promise + async/await
async/await 是基于 Promise 的语法糖,使异步代码的写法更加简洁和同步化。
示例:async/await 基本用法
// async/await 版本
async function fetchAllData() {
try {
const data1 = await fetchData(1000, "数据1");
console.log("成功获取数据:", data1);
const data2 = await fetchData(1000, "数据2");
console.log("成功获取数据:", data2);
const data3 = await fetchData(1000, "数据3");
console.log("成功获取数据:", data3);
} catch (err) {
console.error("操作失败:", err);
}
}
fetchAllData();
解释:
async标记一个函数为异步函数,该函数总是返回一个Promise。await用于等待Promise完成并返回结果,语法看起来像是同步的。try/catch结构用于捕获错误。
3. 串联操作 (Chaining)
串联操作是指多个异步操作按顺序执行,只有前一个操作成功后,才会执行下一个操作。
示例:Promise 串联操作(使用 .then())
function fetchDataWithDelay(delay, result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`成功获取数据: ${result}`);
resolve(result); // 模拟异步操作成功
}, delay);
});
}
// 使用 .then() 串联多个 Promise 操作
fetchDataWithDelay(1000, "数据1")
.then((result) => fetchDataWithDelay(1000, "数据2"))
.then((result) => fetchDataWithDelay(1000, "数据3"))
.then((result) => console.log("所有数据都获取成功"))
.catch((error) => console.error("发生错误:", error));
示例:async/await 串联操作
async function fetchDataSequentially() {
try {
await fetchDataWithDelay(1000, "数据1");
await fetchDataWithDelay(1000, "数据2");
await fetchDataWithDelay(1000, "数据3");
console.log("所有数据都获取成功");
} catch (error) {
console.error("发生错误:", error);
}
}
fetchDataSequentially();
解释:
- 串联:每个异步操作会按顺序执行,只有当前一个操作成功(
resolve)后,才会执行下一个操作。 .then()和async/await都可以用于串联多个异步操作。
4. 并行操作 (Parallel Execution)
并行操作是指多个异步操作同时执行,减少等待时间,适用于独立的异步任务。
示例:Promise 并行操作(使用 Promise.all())
function fetchDataWithDelay(delay, result) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`成功获取数据: ${result}`);
resolve(result); // 模拟异步操作成功
}, delay);
});
}
// 使用 Promise.all() 执行并行操作
Promise.all([
fetchDataWithDelay(1000, "数据1"),
fetchDataWithDelay(500, "数据2"),
fetchDataWithDelay(1500, "数据3")
])
.then((results) => {
console.log("所有数据都获取成功:", results);
})
.catch((error) => {
console.error("发生错误:", error);
});
示例:async/await 并行操作
async function fetchDataInParallel() {
try {
const results = await Promise.all([
fetchDataWithDelay(1000, "数据1"),
fetchDataWithDelay(500, "数据2"),
fetchDataWithDelay(1500, "数据3")
]);
console.log("所有数据都获取成功:", results);
} catch (error) {
console.error("发生错误:", error);
}
}
fetchDataInParallel();
解释:
Promise.all():将多个Promise放入一个数组,并行执行。当所有Promise都成功时,then()会被触发;只要其中一个失败,catch()会被触发。async/await配合Promise.all()也可以执行并行操作,所有操作并行执行,直到它们都完成。
5. 串联 vs 并行
串联 (Sequential)
- 每个异步操作必须等待前一个操作完成后才能执行。
- 示例:下载多个文件时,必须按照顺序下载。
并行 (Parallel)
- 所有异步操作可以同时开始,减少等待时间。
- 示例:并发获取多个 API 数据,提高效率。
总结:
.then()和.catch():通过链式调用来处理Promise,适合处理按顺序执行的异步任务。async/await:使代码看起来像同步操作,适合处理复杂的异步逻辑,代码更简洁。- 串联:当异步操作需要按顺序执行时使用。
- 并行:当多个异步操作可以同时进行时使用
Promise.all()或async/await配合。