Promise的核心作用是将嵌套回调改为平铺链式调用,通过then链实现线性流程、统一catch错误处理、封装回调API为Promise、支持Promise.all()并行与Promise.race()竞速。

Promise 的核心作用,就是把层层嵌套的回调函数,变成一条平铺、可读、易维护的链式调用。它不改变异步本质,但彻底重构了写法逻辑。
用 then 链替代多层嵌套
传统回调地狱中,每个新请求都得塞进上一个回调里,缩进越来越深,逻辑被“压扁”在右侧:
```js
getUser(id, (user) => {
getPosts(user.id, (posts) => {
getComments(posts[0].id, (comments) => {
console.log(comments);
});
});
});
```
改用 Promise 后,每个异步操作返回 Promise,用 then 依次承接结果:
- 每个 then 接收上一步成功返回的值
- 若该 then 中返回一个新的 Promise(比如发起下一个请求),链会自动等待它完成再进入下一个 then
- 代码从“右深缩进”变成“自上而下”的线性流程
```js
getUser(id)
.then(user => getPosts(user.id))
.then(posts => getComments(posts[0].id))
.then(comments => console.log(comments))
.catch(err => console.error(err));
```
统一错误处理,不用每层写 error 回调
回调地狱里,每个层级都要单独处理失败情况,容易遗漏或重复:
```js
getUser(id, (err, user) => {
if (err) return handleError(err);
getPosts(user.id, (err, posts) => {
if (err) return handleError(err);
getComments(posts[0].id, (err, comments) => {
if (err) return handleError(err);
console.log(comments);
});
});
});
```
Promise 中只需一个 catch,就能捕获链中任意环节抛出的错误(包括 reject 和同步异常):
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- catch 会捕获前面所有 then 中未处理的拒绝态和 throw 出的错误
- 位置灵活:放在末尾是全局兜底;插在中间可局部容错,不影响后续流程
```js
getUser(id)
.then(user => getPosts(user.id))
.catch(err => {
console.warn('获取用户或帖子失败,降级处理');
return fallbackPosts(); // 返回新 Promise 或默认值
})
.then(posts => getComments(posts[0].id))
.then(console.log)
.catch(err => console.error('最终失败:', err));
```
把老式回调 API 包装成 Promise
很多底层 API(如 Node.js 的 fs.readFile、浏览器的 XMLHttpRequest)仍是回调风格。要接入 Promise 链,需手动封装:
- 用 new Promise 包一层,把 resolve/reject 映射到回调的 success/error 分支
- 封装后得到标准 Promise,可直接参与链式调用
```js
function readFileAsync(file) {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf8', (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
}
// 现在可以自然链式使用
readFileAsync('./config.json')
.then(JSON.parse)
.then(config => fetch(`/api/${config.endpoint}`))
.then(res => res.json())
.then(console.log);
```
并行与竞速:Promise.all() 和 Promise.race()
当多个异步任务无依赖关系时,不必串行等待,可用组合方法提升效率:
- Promise.all([p1, p2, p3]):全部成功才算成功,返回结果数组;任一失败则整体失败
- Promise.race([p1, p2, p3]):谁先结束(无论成败)就用谁的结果
例如同时加载多个配置文件,或设置超时限制:
```js
// 并行请求多个接口
Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
])
.then(([usersRes, postsRes, commentsRes]) =>
Promise.all([
usersRes.json(),
postsRes.json(),
commentsRes.json()
])
)
.then(([users, posts, comments]) => render({ users, posts, comments }));
// 设置 5 秒超时
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), 5000)
);
Promise.race([fetch('/api/data'), timeout])
.then(res => res.json())
.catch(err => console.error(err.message));
```
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










