Promise 是 JavaScript 异步编程的正式抽象层,本质是封装 pending→fulfilled/rejected 状态迁移的异步容器;通过 then/catch 实现可组合、可中断、统一错误处理的链式流程。
Promise 不是语法糖,而是 JavaScript 异步编程的正式抽象层;它本身不消除回调,但通过状态机和规范化的 then / catch 接口,让异步流程可组合、可中断、可统一错误处理。
Promise 本质是

executor,它会**立即同步执行**,且只执行一次resolve 和 reject 是 executor 的两个参数,调用它们才会触发状态变更fulfilled 或 rejected,就不可逆,后续所有 then / catch 都只能读取该终态then 的返回值产生新 Promise,形成链式结构回调地狱的本质是「在回调里写回调」,根源在于每个异步操作都强制要求你立刻处理结果。Promise 的 then 改变了这个规则:它不要求你立刻消费结果,而是允许你返回一个新值或新 Promise,由下一级 then 继续处理。
fetch('/api/user')
.then(response => response.json())
.then(user => fetch(`/api/posts?uid=${user.id}`))
.then(response => response.json())
.then(posts => console.log(posts))
.catch(err => console.error('出错了', err));
then 的回调函数只专注一件事:转换上一步的结果,或发起下一个异步操作then 会立即收到它;如果返回的是 Promise,下个 then 会等它 settle 后再执行fetch 成功响应不等于 HTTP 状态码 200,response.ok 才是判断依据,否则会掉进「成功回调里抛错」的坑catch 实际是 then(undefined, onRejected) 的语法糖,它只会捕获「前一个 Promise 的 rejection」,而不是整条链路上所有可能的异常。中间某个 then 抛出同步错误(比如 JSON.parse(null)),或者返回了一个立刻 reject 的 Promise,都会被紧随其后的 catch 捕获,但跳过前面的 catch。
catch 写在第一个 then 后面,以为能兜住所有后续错误 → 实际只捕获第一个请求失败then 后都接 catch(适合需差异化处理的场景),要么统一放在链末(适合全局兜底)async/await 中的 try/catch 行为与此一致——它捕获的是当前 await 表达式产生的 rejection,不是整个函数体Promise 的行为边界比直觉中更严格,很多“看似合理”的写法会导致静默失败或意外阻塞:
Promise.resolve().then(() => { throw new Error('boom') }) 不会崩掉主线程,但错误会被丢弃,除非链上有 catch
then 注册在同一个 Promise 上,它们是并发执行的,不是排队等待前一个完成(因为每个 then 都返回新 Promise)Promise.all([p1, p2]) 在任意一个 reject 时就立刻 reject,如果需要全部结果(含失败),得用 Promise.allSettled