Promise 是封装未来完成或失败异步操作的对象,非语法糖或同步魔法;它立即执行 executor,通过 .then/.catch 处理结果,链式调用返回新 Promise;async/await 是其语法糖,await 不阻塞线程但需 try/catch 捕错。

Promise 是什么,不是什么
Promise 不是语法糖,也不是让异步变同步的魔法。它是一个对象,用来封装一个**尚未完成但未来会完成(或失败)的异步操作**,并提供统一的 .then()/.catch() 接口处理结果。
常见误解是把它当“等待器”——new Promise() 立即执行 executor 函数,内部的异步逻辑(比如 setTimeout 或 fetch)才决定 resolve/reject 的时机。Promise 本身不暂停代码执行。
- 构造时传入的函数(executor)是同步运行的,但通常在里面启动异步任务
-
Promise.resolve(value)和Promise.reject(reason)用于快速创建已决议的 Promise - 链式调用中,每个
.then()返回的是**新 Promise**,值传递靠 return,错误传递靠 throw 或返回 rejected Promise
async/await 是 Promise 的语法糖,不是新机制
async 函数必定返回 Promise,哪怕你写 return 42,实际返回的是 Promise.resolve(42);await 只是让 JS 引擎在遇到 Promise 时暂停当前 async 函数的执行,等它 settled 后再继续——它不阻塞线程,也不影响事件循环。
注意:await 只能在 async 函数内使用,顶层 await 仅在模块(type="module")中有效。
立即学习“Java免费学习笔记(深入)”;
-
await后面不强制是 Promise,非 Promise 值会被自动包装成 resolved Promise - 错误必须用
try/catch捕获,.catch()在 async 函数外才能接住抛出的异常 - 多个独立请求别用
await串行写,该用Promise.all([p1, p2])并发发
常见错误:混淆状态、忽略错误、滥用 await
最典型的问题是以为 await promise 能“修复”被 reject 的 Promise——其实它只是把 rejection 变成 throw,不 catch 就崩。
另一个高频坑是把本可并发的请求写成串行:
async function bad() {
const a = await fetch('/api/a').then(r => r.json());
const b = await fetch('/api/b').then(r => r.json()); // 等 a 完了才发 b
return [a, b];
}
正确做法是先发两个请求,再 await 它们的结果:
async function good() {
const [a, b] = await Promise.all([
fetch('/api/a').then(r => r.json()),
fetch('/api/b').then(r => r.json())
]);
return [a, b];
}
- 忘记处理 reject → 页面白屏或静默失败;加
try/catch或在最后链.catch(console.error) - 在循环里直接 await → 实际是串行,性能差;需用
map().map(p => p.then(...))或Promise.allSettled() - 用
await包裹已执行完的 Promise → 没必要,纯属多绕一层
调试 Promise 链和 await 的实际技巧
Chrome 和 Firefox 控制台能显示 Promise 状态(pending/resolved/rejected),但不会显示中间 resolve 值。想看清每一步,要么加 console.log,要么用 async 函数拆分逻辑块。
Node.js 中可通过 --trace-warnings 暴露未捕获的 Promise rejection;浏览器可用 window.addEventListener('unhandledrejection', ...) 兜底。
- 链式调用过长时,优先拆成小的
async函数,比堆.then().then().then()更易读 -
await Promise.resolve().then(...)是无效延迟,等同于直接执行;真要微任务延迟,用await Promise.resolve() - 测试时模拟 reject,别只 mock 成功路径;用
jest.mock或sinon.stub().rejects()覆盖错误分支











