JavaScript 的 Promise 用法详解及使用场景
Promise 是 JavaScript 中用于管理异步操作的对象,可以让代码更加简洁、可读,并且避免“回调地狱”。以下是 Promise 的详细用法及其适用场景。
一、Promise 的核心概念
- 状态(State)
pending:初始状态,表示操作未完成。
fulfilled:操作成功完成。
rejected:操作失败。 - 状态特点
状态一旦从 pending 转为 fulfilled 或 rejected,便不可再更改。
一个 Promise 只能有一个最终状态(成功或失败)。 - 构造函数
创建 Promise 的语法:const promise = new Promise((resolve, reject) => { // 异步操作 if (操作成功) { resolve(成功值); } else { reject(失败原因); } });
二、Promise 的用法详解
-
基本用法
const promise = new Promise((resolve, reject) => { let isSuccess = true; if (isSuccess) { resolve("操作成功"); } else { reject("操作失败"); } }); promise .then((result) => { console.log(result); // 操作成功 }) .catch((error) => { console.error(error); // 操作失败 });
-
链式调用
• then() 方法会返回一个新的 Promise,因此可以链式调用来处理多个异步操作。new Promise((resolve) => resolve(2)) .then((value) => { console.log(value); // 输出 2 return value * 2; }) .then((value) => { console.log(value); // 输出 4 return value * 3; }) .then((value) => { console.log(value); // 输出 12 });
-
错误处理
• 使用 catch() 捕获 Promise 中的错误。new Promise((resolve, reject) => { reject("发生错误"); }) .then((value) => { console.log(value); // 不会执行 }) .catch((error) => { console.error(error); // 发生错误 });
• 错误会沿着链条传递,直到被 catch 捕获。
new Promise((resolve, reject) => { reject("错误1"); }) .then(() => { console.log("成功1"); }) .then(() => { console.log("成功2"); }) .catch((error) => { console.error(error); // 捕获 "错误1" });
-
finally() 方法
• finally() 方法会在 Promise 结束后(无论是成功还是失败)执行操作。new Promise((resolve) => resolve("操作完成")) .then((result) => { console.log(result); // 操作完成 }) .finally(() => { console.log("结束操作"); // 始终执行 });
三、Promise 的静态方法
-
Promise.resolve()
• 创建一个已成功的 Promise。Promise.resolve("快速成功").then((value) => console.log(value)); // 快速成功
-
Promise.reject()
• 创建一个已失败的 Promise。Promise.reject("快速失败").catch((error) => console.error(error)); // 快速失败
-
Promise.all()
• 等待所有 Promise 完成,返回包含结果的数组;若有一个失败,则整个返回失败。const p1 = Promise.resolve(1); const p2 = Promise.resolve(2); const p3 = Promise.reject("失败"); Promise.all([p1, p2]) .then((results) => console.log(results)) // [1, 2] .catch((error) => console.error(error)); // 不会执行 Promise.all([p1, p2, p3]) .then((results) => console.log(results)) // 不会执行 .catch((error) => console.error(error)); // 失败
-
Promise.allSettled()
• 等待所有 Promise 完成,无论成功或失败,返回每个 Promise 的结果。Promise.allSettled([ Promise.resolve("成功"), Promise.reject("失败"), ]).then((results) => console.log(results)); /* 输出: [ { status: "fulfilled", value: "成功" }, { status: "rejected", reason: "失败" } ] */
-
Promise.race()
• 返回第一个完成的 Promise(无论成功还是失败)。const p1 = new Promise((resolve) => setTimeout(() => resolve("慢"), 100)); const p2 = new Promise((resolve) => setTimeout(() => resolve("快"), 50)); Promise.race([p1, p2]).then((value) => console.log(value)); // 快
-
Promise.any()
• 返回第一个成功的 Promise;如果所有 Promise 都失败,则返回 AggregateError。Promise.any([ Promise.reject("失败1"), Promise.reject("失败2"), Promise.resolve("成功"), ]).then((value) => console.log(value)); // 成功 Promise.any([ Promise.reject("失败1"), Promise.reject("失败2"), ]).catch((error) => console.error(error.errors)); // ["失败1", "失败2"]
四、Promise 的使用场景
-
异步请求
• 使用 Promise 处理 HTTP 请求,链式调用后处理数据。fetch("https://jsonplaceholder.typicode.com/posts/1") .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error("请求失败", error));
-
多个异步操作并发处理
• 使用 Promise.all() 同时执行多个请求。const fetch1 = fetch("https://jsonplaceholder.typicode.com/posts/1"); const fetch2 = fetch("https://jsonplaceholder.typicode.com/posts/2"); Promise.all([fetch1, fetch2]) .then((responses) => Promise.all(responses.map((res) => res.json()))) .then((data) => console.log(data)) .catch((error) => console.error(error));
-
异步任务的错误恢复
• 使用 catch 捕获错误并进行恢复操作。fetch("https://jsonplaceholder.typicode.com/posts/1") .then((response) => { if (!response.ok) { throw new Error("网络错误"); } return response.json(); }) .catch((error) => { console.error("捕获错误:", error); return { error: "默认值" }; }) .then((data) => console.log(data));
-
动画控制
• 配合 setTimeout 或动画框架(如 GSAP)实现动画序列。function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } delay(1000) .then(() => { console.log("1秒后执行"); return delay(2000); }) .then(() => { console.log("再过2秒执行"); });
五、总结
- Promise 的优点:
o 更优雅的异步编程方式。
o 避免回调地狱,代码更加易读。
o 提供了丰富的静态方法处理复杂异步操作。 - 适用场景:
o 异步请求和数据处理。
o 并发任务管理。
o 动画与计时操作。
o 错误处理和恢复。