Promise 是表示异步操作状态的对象,有 pending/fulfilled/rejected 三种不可逆状态;async/await 是其语法糖,使异步代码更同步化、错误处理更直观、调试更方便,二者底层一致但适用场景不同。

Promise 和 async/await 都是用来处理 JavaScript 异步操作的机制,async/await 本质上是 Promise 的语法糖,让异步代码写起来更像同步代码,可读性更强,错误处理也更自然。
Promise 是什么?怎么用?
Promise 是一个表示异步操作最终完成或失败的对象。它有三种状态:pending(进行中)、fulfilled(成功)、rejected(失败)。一旦状态改变,就不会再变。
- 用 new Promise((resolve, reject) => {...}) 创建,内部调用 resolve 或 reject 切换状态
- 用 .then() 处理成功结果,.catch() 捕获错误,.finally() 无论成败都执行
- 多个异步任务可以链式调用:
promise1.then().then().catch(),但嵌套深了容易“回调地狱”感 - Promise.all([]) 并行执行多个 Promise,全部成功才 resolve;Promise.race([]) 返回第一个 settled 的结果
async/await 是怎么工作的?
async 函数返回一个 Promise 对象,await 只能在 async 函数内部使用,它会“暂停”函数执行,等待右侧的 Promise settle 后继续,并直接拿到 resolved 的值(reject 会抛出异常)。
- 函数前加 async 关键字,就自动包装成 Promise,即使 return 基本类型也会被 Promise.resolve() 包裹
- await 后面不一定是 Promise,但会自动用 Promise.resolve() 转换;如果是 rejected Promise,会触发 try/catch 中的 catch 分支
- 错误处理更直观:用 try/catch 就能捕获 await 抛出的异常,不用分散写 .catch()
- 并行执行多个异步操作时,别忘了先 let p1 = promise1(), p2 = promise2(),再 await Promise.all([p1, p2]),否则就变成串行了
关键区别在哪?
不是“谁更好”,而是适用场景和表达习惯不同:
立即学习“Java免费学习笔记(深入)”;
- 错误处理方式不同:Promise 靠 .catch(),容易漏掉中间环节;async/await 用 try/catch,结构清晰,异常冒泡行为更可控
- 调试体验不同:await 行可以直接打断点,执行流停在那;Promise 链里的 .then 回调在另一个微任务里,堆栈不连贯
- 条件逻辑更自然:比如“如果 A 成功就执行 B,否则跳过”,用 await + if 很直白;Promise 需要 .then 中 return 新 Promise 或嵌套,易出错
- 底层没区别:await foo() 等价于 foo().then(value => value),编译后仍是 Promise 链,只是 V8 引擎做了语法层面的暂停模拟
什么时候该选哪个?
日常开发中优先用 async/await,尤其涉及多步骤、有判断、需调试的逻辑;但在工具函数或需要组合多个 Promise 的场景,原生 Promise API 更灵活:
- 写库或通用工具函数(如封装请求重试)——常用 Promise 构造和静态方法,更底层可控
- 简单的一次性异步调用(如初始化加载)——async/await 写起来快、易维护
- 需要精确控制并发数量(如限制同时 3 个请求)——结合 Promise.allSettled 和队列管理,比 await 更合适
- 浏览器兼容要求高(如还要支持 IE)——Promise 需 polyfill,async/await 必须转译(Babel),成本略高
基本上就这些。用熟 Promise 是理解 async/await 的基础,而掌握 async/await 能让异步逻辑回归“线性思维”。两者配合着用,不冲突也不重复。











