红宝书第十七讲:通俗详解JavaScript的Promise与链式调用
资料取自《JavaScript高级程序设计(第5版)》。
查看总目录:红宝书学习大纲
一、Promise的作用:解决“回调地狱”的困境
Promise(承诺)是JavaScript管理异步操作的工具,用于替代传统的嵌套回调链(回调地狱)。它能将异步代码线性化,让异步逻辑像步骤说明书一样清晰 12。
传统回调地狱的代码(难以阅读和维护):
// 示例:依次执行多个异步任务(层层嵌套的“金字塔”)
delayedExecute('第一步', (result1) => {
delayedExecute('第二步', (result2) => {
delayedExecute('第三步', (result3) => { // 层层缩进 → 难以维护
// ...
});
});
});
Promise链式调用的代码(清晰易读):
fetchData()
.then((result1) => process(result1)) // 步骤1
.then((result2) => process(result2)) // 步骤2
.then((result3) => process(result3)) // 步骤3
.catch((error) => console.error(error)); // 统一错误处理
1: 资料2提到Promise/A+规范用于统一异步编程模式
2: 资料5对比回调地狱与Promise链式调用的代码结构优势
二、Promise的状态:3个阶段
每个Promise对象有3种状态 1:
- Pending(等待中):初始状态,尚未完成
- Fulfilled(已成功):异步操作成功完成
- Rejected(已失败):异步操作失败或出现错误
三、链式调用:像流水线一样处理异步任务
链式调用的核心在于:每个then()
/catch()
/finally()
都会返回一个新的Promise,允许后续继续调用 32。
示例:分步骤模拟异步操作
// 创建返回Promise的简单异步函数
function delay(ms, value) {
return new Promise((resolve) => {
setTimeout(() => resolve(value), ms);
});
}
// 链式调用示例 → 每个then等待前一步完成
delay(1000, "第一步数据")
.then((data) => {
console.log(`收到:${data}`);
return delay(1000, "第二步处理后的数据"); // 返回新Promise
})
.then((data) => {
console.log(`收到:${data}`);
return "直接返回的第三步结果(非Promise)";
})
.then(console.log); // 自动包装为已成功的Promise
// 输出:
// (1秒后)收到:第一步数据
// (2秒后)收到:第二步处理后的数据
// (2秒后)直接返回的第三步结果...
3: 资料1说明then/catch的链式返回新Promise对象
2: 资料5展示通过then链式严格排序的异步执行
流程图解释链式调用:
四、错误处理:统一捕获异常
通过catch()
集中处理链中的任何错误,不影响后续步骤 34。
示例:错误捕获后继续执行
fetchData()
.then(processStep1)
.then(() => { throw new Error("故意抛出错误"); }) // 中途出错
.catch((error) => {
console.error(`捕获错误:${error}`);
return "错误后的恢复数据";
})
.then((data) => console.log(`继续处理:${data}`)); // 继续链式
// 输出:
// 捕获错误:故意抛出错误
// 继续处理:错误后的恢复数据
4: 资料6中通过catch处理多个请求的集合错误
五、应用场景与扩展知识
- 多个异步任务并行(
Promise.all([任务1, 任务2])
)4 - 仅需第一个完成的任务(如竞速请求:
Promise.any([任务1, 任务2])
)4 - 统一清理资源(
finally(() => { ... })
,无论成功失败都会执行)
目录:总目录
上篇文章:红宝书第十六讲:通俗详解JavaScript回调函数与事件循环
下篇文章:红宝书第十八讲:详解JavaScript的async/await与错误处理
脚注
- 《JavaScript高级程序设计(第5版)》提及Promise状态机与异步编程模式 ↩
- 《JavaScript高级程序设计(第5版)》对比传统回调与Promise链式代码结构 ↩
- 《JavaScript高级程序设计(第5版)》指出链式调用基于每个方法返回新Promise ↩
- 《JavaScript高级程序设计(第5版)》说明使用Promise.any()处理最快响应结果 ↩
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。