async/await 是 Promise 的语法封装而非语法糖,async 函数自动返回 Promise,await 必须在 async 函数内使用,错误需用 try/catch 捕获,多请求应优先用 Promise.all 并发。

async/await 不是语法糖的替代品,而是 Promise 的语法封装;它不能消除异步本质,但能显著降低回调嵌套和错误处理的复杂度。
async 函数必须显式返回 Promise
声明为 async function 的函数,无论内部是否用 await,其返回值都会被自动包装成 Promise。直接 return 一个普通值(如 return 42),等价于 return Promise.resolve(42);如果 throw 错误,则等价于 return Promise.reject(error)。
常见错误:在 async 函数里忘记 await 调用另一个 async 函数,导致返回的是 pending Promise 而非实际值。
- ✅ 正确写法:
const data = await fetchUser(); - ❌ 错误写法:
const data = fetchUser(); // data 是 Promise,不是用户对象 - ⚠️ 注意:顶层 await 只在模块作用域(.mjs 或
type="module"script)中合法,普通脚本中会报SyntaxError: await is only valid in async function
await 只能在 async 函数内部使用
await 不是全局操作符,它依赖 async 函数提供的执行上下文来暂停和恢复执行。试图在普通函数、事件回调、或 for 循环顶层直接写 await 都会触发语法错误。
立即学习“Java免费学习笔记(深入)”;
典型场景:想在点击事件里等待 API 响应,但忘了把事件处理函数声明为 async。
Android高手进阶教程(八)之----Android Widget开发案例(世界杯倒计时!),主要向大家讲解使用Android Widget如何编写出一款世界杯风格的倒计时程序,教程说出了制作步骤和代码。
- ✅ 正确:
button.addEventListener('click', async () => { const res = await apiCall(); render(res); }); - ❌ 报错:
button.addEventListener('click', () => { const res = await apiCall(); }); // Uncaught SyntaxError - ? 补充:箭头函数也需加
async,不能只靠外层函数“传染”
错误处理要用 try/catch,而不是 .catch()
await 会让 Promise rejection 变成同步抛出的异常,因此必须用 try/catch 捕获——用 .catch() 会失效,因为 await 已经把链式调用“打断”了。
容易踩的坑:混用 await 和 .catch(),以为能兜住错误,结果未捕获的 rejection 触发 Uncaught (in promise)。
- ✅ 推荐:
try { const data = await fetch('/api').then(r => r.json()); } catch (err) { console.error('请求失败', err); } - ❌ 无效:
await fetch('/api').catch(handleError); // catch 不会阻止 rejection 向上冒泡 - ⚠️ 注意:
await Promise.reject('boom')会立即进入 catch 分支,行为完全同步可预测
多个异步操作的并发控制要小心
await 默认是串行的:前一个没结束,后一个不开始。想并行发起多个请求(比如同时拉用户信息和订单列表),得用 Promise.all() 包装,而不是连续 await。
性能影响明显:串行 await 5 个 200ms 请求耗时约 1s;Promise.all([a(), b(), c()]) 理论上只要最慢那个的时间(200ms)。
- ✅ 并行:
const [user, orders] = await Promise.all([fetchUser(), fetchOrders()]); - ❌ 串行(低效):
const user = await fetchUser(); const orders = await fetchOrders(); - ? 提示:
Promise.allSettled()更适合容错场景,避免单个失败导致全部中断
真正难的从来不是写对 async/await,而是判断哪些操作该串行、哪些该并行、哪些该降级或超时控制——这些逻辑不会因语法变简洁而自动消失。










