Promise 的核心是解决回调嵌套深、状态不明确、错误处理分散三大问题,通过封装状态、显式 resolve/reject、链式 then/catch 实现异步流程可读可维护。

从入门到熟练掌握 Promise,关键不是背语法,而是理解它解决的实际问题和内在逻辑。学得扎实的人,往往不是最早写 .then() 的,而是最先看清“为什么非得用 Promise”的人。
先搞懂它为什么存在
Promise 不是凭空加的功能,它直接回应三个现实痛点:
- 回调嵌套太深——登录后查用户,查完再查订单,再查详情,代码缩进像楼梯,读起来要反复跳转
- 状态不明确——异步操作到底进行中、成功了、还是失败了?靠“有没有调回调”去猜,容易漏判
- 错误处理分散——每个回调里都得写自己的
if (err),一漏就崩,还不好统一拦截
Promise 把这三件事变成显式动作:一个对象封装状态,resolve 和 reject 明确表态,.then() 和 .catch() 统一收口。这不是炫技,是让异步流程可读、可测、可维护。
亲手创建并观察它的状态流转
别跳过手写 Promise 实例这一步。打开控制台,敲几行最简代码:
const p = new Promise((resolve, reject) => {
console.log('executor 立即执行');
setTimeout(() => {
Math.random() > 0.5 ? resolve('成功') : reject('失败');
}, 1000);
});
console.log('Promise 已创建,当前状态:pending');
你会看到:executor 立刻运行,Promise 创建完就是 pending,一秒后才变 fulfilled 或 rejected。重点体会三点:
- 状态不可逆:一旦
resolve,再调reject无效;反之亦然 - executor 自动触发:不用
.start()或.run(),new 就执行 - 结果只传一次:
.then()后续无论何时添加,只要状态已定,立刻拿到值或错
用链式调用替代嵌套,写出真正“自上而下”的代码
把以前的回调嵌套改写成 Promise 链,是最有效的练习。例如:
- 原写法:
login(..., (user) => { getUser(user.id, (info) => { ... }) }) - 改写后:
login().then(user => getUser(user.id)).then(info => ...)
注意每一步返回什么:
- 如果
.then()回调里返回一个普通值(比如字符串、数字),下一级.then()会收到它 - 如果返回一个新的 Promise,下一级会等它 settled 后再执行,自动“接住”它的结果
- 如果抛错(
throw new Error),会跳到最近的.catch(),不用手动传error
错误处理必须落到链上,而不是每个环节各自为政
初学者常犯的错是每个 .then() 都写两个参数,或者在每层里 try/catch。正确做法是:
- 主链用
.then()处理成功路径,只写一个参数 - 整个链末尾加一个
.catch(),它能捕获链上任意位置抛出的错误或被reject的 Promise - 需要局部容错时,可在某步用
.catch(() => {/* 返回默认值 */})拦截并“兜底”,不让错误继续向下游传播
这样既集中管理异常,又保留灵活兜底能力,比到处写 if (err) 清晰得多。











