Promise 是封装异步操作的状态容器,有 pending、fulfilled、rejected 三种不可逆状态;then 注册响应处理器并返回新 Promise,catch 应置于链尾统一捕获所有错误;构造函数执行器同步运行。

Promise 是什么:它不是回调函数的语法糖,而是异步操作的状态容器
Promise 本质是一个对象,用来封装一个**尚未完成但终将完成(或失败)的异步操作**。它有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。状态一旦改变(fulfilled 或 rejected),就不可逆,也不会再变。
和直接写 setTimeout 或 XMLHttpRequest 回调不同,Promise 把“操作”和“响应”解耦了——你创建 Promise 时就定义好它“做什么”,之后用 then 和 catch 去声明“成功后怎么做”“失败后怎么做”,而不是把逻辑嵌在回调里。
如何正确使用 then:它接收两个可选函数,但只处理上一个 Promise 的结果
then 不是“等异步结束就执行”,而是“注册对前一个 Promise 状态的响应处理器”。它的第一个参数处理 fulfilled,第二个参数处理 rejected(但不推荐在这里捕获错误)。
-
then总是返回一个新的 Promise,所以可以链式调用;返回值会自动包装成 resolved Promise,抛出异常则变成 rejected - 如果只想处理成功,第二个参数留空或传
undefined,别写null(会报错) - 不要在
then的第二个参数里做复杂错误处理——它无法捕获第一个参数内部抛出的错误(比如throw new Error()),这部分会被忽略,导致静默失败
fetch('/api/user')
.then(response => {
if (!response.ok) throw new Error('HTTP error');
return response.json();
})
.then(data => console.log(data))
.catch(err => console.error('出错了:', err)); // 所有 reject 和上面 throw 都会进这里
为什么 catch 必须放在链尾,而不是每个 then 后面都加
catch 是 then(undefined, rejectionHandler) 的语法糖,但它能捕获链中**任何上游 Promise 的 rejection**,包括 then 回调里抛出的错误。如果在每个 then 后都跟 catch,不仅冗余,还会中断链式流程——一旦某个 catch 处理完错误并没重新抛出,后续 then 仍会执行(因为 catch 返回的是 fulfilled Promise)。
立即学习“Java免费学习笔记(深入)”;
- 常见错误:写成
.then(...).catch(...).then(...),以为第二个then只在成功时运行,其实它也会收到前一个catch的返回值 - 正确做法:单个
catch放在链最末,覆盖整条链的异常流 - 极少数需要局部容错时,可在某步
then内部用try/catch,或返回Promise.resolve().catch(...)转换错误为值
容易被忽略的关键点:Promise 构造函数里的执行器是同步运行的
很多人误以为 new Promise(() => {...}) 里的函数是“异步执行”的,其实它**立即同步执行**。里面的 resolve 或 reject 调用也同步发生,只是 Promise 的 then / catch 回调会被推入微任务队列,等当前同步代码跑完才执行。











