Promise 基础
掌握 Promise 创建、then/catch、链式调用
Promise 基础
回调函数的问题是"回调地狱"——嵌套越来越深,错误处理分散,流程难以控制。Promise 用链式调用解决了这个痛点,是 JavaScript 异步编程的基础。
学完本章你将: 理解 Promise 的状态机制、then/catch 链式调用、静态方法。
Promise 是什么
Promise 就是一个承诺:"我将来会给你一个结果,要么成功要么失败"。它有且只有三种状态,一旦确定永不改变。
pending(等待中)
↙ ↘
fulfilled(成功) rejected(失败)
// 创建一个 Promise:传入的函数立即执行
let promise = new Promise((resolve, reject) => {
// setTimeout 模拟异步操作(比如网络请求)
setTimeout(() => {
let success = true;
if (success) {
resolve("操作成功!"); // 成功 → 状态变为 fulfilled
} else {
reject(new Error("失败!")); // 失败 → 状态变为 rejected
}
}, 1000);
});
// resolve/reject 只能调一个,调完状态就锁死,后面的 resolve/reject 无效
then / catch / finally —— 处理结果
.then() 接收两个函数(成功回调和失败回调),但通常只用第一个,失败交给 .catch()。
promise
.then(result => { // fulfilled 时执行
console.log("成功:", result);
return result.toUpperCase(); // 返回的值会包装成新 Promise
})
.then(upper => { // 上一个 then 的返回值
console.log("大写:", upper);
})
.catch(error => { // 任意位置 rejected 都会跳到这里
console.error("出错了:", error.message);
})
.finally(() => { // 无论如何都执行
console.log("清理工作");
});
💡 关键:
.then()永远返回新的 Promise,所以可以无限链下去。这就是"链式调用"——比回调嵌套清晰得多。
链式调用 —— 解决回调地狱
// ❌ 回调地狱
getUser(1, (err, user) => {
getPosts(user.id, (err, posts) => {
getComments(posts[0].id, (err, comments) => { /* … */ });
});
});
// ✅ Promise 链
getUser(1)
.then(user => getPosts(user.id))
.then(posts => getComments(posts[0].id))
.then(comments => console.log(comments))
.catch(err => console.error("哪儿出错都到这", err));
静态方法
// Promise.resolve / reject —— 快速创建
Promise.resolve(42).then(n => console.log(n)); // 42
Promise.reject("错").catch(e => console.log(e)); // "错"
// Promise.all —— 全部成功才成功(并发执行)
Promise.all([fetch("/api/users"), fetch("/api/posts")])
.then(([users, posts]) => { /* 两个都拿到了 */ })
.catch(err => { /* 任意一个失败 */ });
// Promise.allSettled —— 等全部完成,不管成败
Promise.allSettled([Promise.resolve(1), Promise.reject("err")])
.then(results => results.forEach(r => console.log(r.status)));
// Promise.race —— 第一个完成的(不管成败)
Promise.race([fetch("/fast"), timeout(5000)]);
// Promise.any —— 第一个成功的(ES2021)
Promise.any([fetch("/mirror1"), fetch("/mirror2")]);
function getUser(id) { return new Promise((resolve) => { setTimeout(() => resolve({ id, name: "Alice" }), 500); }); }
function getPosts(userId) { return new Promise((resolve) => { setTimeout(() => resolve(["post1", "post2"]), 500); }); }
getUser(1) .then(user => { console.log("用户:", user.name); return getPosts(user.id); // 返回新 Promise }) .then(posts => { console.log("帖子:", posts); }) .catch(err => console.error(err));
---
## 静态方法
```javascript
// Promise.resolve
Promise.resolve(42).then(n => console.log(n)); // 42
// Promise.reject
Promise.reject("失败").catch(e => console.log(e));
// Promise.all —— 全部成功才成功
Promise.all([
fetch("/api/user"),
fetch("/api/posts"),
fetch("/api/comments"),
]).then(([user, posts, comments]) => {
console.log("全部完成!");
}).catch(err => {
console.log("任意一个失败 -> catch");
});
// Promise.allSettled —— 等全部完成(不管成功失败)
Promise.allSettled([
Promise.resolve(1),
Promise.reject("err"),
Promise.resolve(3),
]).then(results => {
results.forEach(r => console.log(r.status)); // fulfilled, rejected, fulfilled
});
// Promise.race —— 第一个完成的
Promise.race([
fetch("/api/fast"),
new Promise((_, reject) => setTimeout(() => reject("超时"), 5000)),
]).then(r => r.json());
// Promise.any —— 第一个成功的(ES2021)
Promise.any([
Promise.reject("err1"),
Promise.resolve("ok"),
]).then(r => console.log(r)); // "ok"