JavaScript异步编程主要用回调函数、Promise和async/await,其中Promise是基础抽象,async/await是其语法糖;Promise通过链式调用管理流程并需显式.catch()处理错误,async/await使代码更线性且可用try/catch捕获await及同步错误,但需注意并行需配合Promise.all,新项目推荐优先使用async/await。

JavaScript实现异步编程主要靠回调函数、Promise 和 async/await 三种方式,其中 Promise 是基础抽象,async/await 是其语法糖——它们本质一致,但写法和错误处理逻辑有明显差异。
Promise:用链式调用管理异步流程
Promise 表示一个异步操作的最终完成(或失败)及其结果值。它有 pending、fulfilled、rejected 三种状态,一旦改变不可逆。
- 用 new Promise((resolve, reject) => {...}) 手动封装异步操作
- 通过 .then() 处理成功结果,.catch() 捕获错误,支持链式调用
- 多个异步任务可组合:Promise.all([p1, p2]) 并行执行,Promise.race([p1, p2]) 取最快结果
- 注意:Promise 内部错误不会自动抛到外层 try/catch,必须显式用 .catch() 或在末尾加 .catch(console.error)
async/await:让异步代码看起来像同步
async 函数返回一个 Promise 对象,await 只能在 async 函数内使用,会暂停执行直到 Promise settle(完成或拒绝),然后继续。
- await 后面跟 Promise:自动解包 fulfilled 值;若 Promise rejected,会抛出错误,可用 try/catch 捕获
- 相比 Promise 链,代码更线性,嵌套少,调试更直观(堆栈更清晰)
- 不能直接 await 多个独立异步操作:想并行应先用 const [a, b] = await Promise.all([p1(), p2()])
- await 不会阻塞整个 JS 线程,只是暂停当前 async 函数的执行,其他任务仍可运行
关键区别:错误处理与执行控制
Promise 的错误需靠 .catch() 传递,链中任一环节出错都会跳转到最后的 catch;async/await 错误行为更接近同步代码,try/catch 范围明确,但容易漏写 try 导致未捕获异常。
立即学习“Java免费学习笔记(深入)”;
- Promise 链中,.then(f1).then(f2).catch(e):f1 抛错或返回 rejected Promise,都会触发 catch
- async/await 中,try { await p(); await q(); } catch(e) { }:仅捕获 await 表达式抛出的错误,普通语句错误也能被捕获
- await 无法像 .then() 那样自然实现“错误后继续”,需手动用 await p().catch(() => null) 或封装成安全调用函数
实际选择建议
新项目优先用 async/await,逻辑清晰、可读性强;但理解 Promise 是前提——因为 await 本质就是语法糖,底层仍是 Promise 状态机。
- 简单单个异步操作:await 更简洁
- 复杂依赖关系(如 a→b→c):async/await 层次分明
- 多个无依赖异步并行:Promise.all + await 最常用
- 需要精细控制 Promise 状态(如取消、进度监听):仍需直接操作 Promise 实例或配合 AbortController











