async/await vs Promise
Async/await vs Promise
一句话:async/await是 Promise 的语法糖—— 同一套机制,但把「链式回调」写成了 「像同步一样往下读」。async 函数 永远返回一个 Promise。
.then() 链 | async/await | |
|---|---|---|
| 可读性 | 嵌套一深就难读 | 线性,好读 |
| 错误处理 | .catch() | 普通 try/catch——和同步代码统一了 |
| 调试 | 断点难打,栈信息乱 | 能逐行断点,栈清楚 |
| 中间变量 | 要靠嵌套或额外传参才能共享 | 就是普通局部变量 |
| 并发 | 天然并行(先建好再 all) | 容易写成串行—— 这是最常见的性能错误 |
那个「容易写成串行」的坑值得单独说: 两个互不依赖的请求, 写成两行 await就变成了「等第一个回来再发第二个」, 总耗时是两者之和。正确做法是先都发出去,再一起await Promise.all。
会追问:「什么时候还是用 .then 更好?」—— 只需要一步、不需要中间变量时; 或者要故意不等(fire and forget)。 另外 .then在需要把 Promise 存起来传递时更自然。
In one line: async/await is syntax sugar over Promises — the same machinery, but a chain of callbacks now reads straight down like synchronous code. An async function always returns a Promise.
A .then() chain | async/await | |
|---|---|---|
| Readability | Hard to follow the moment it nests | Linear, easy to read |
| Error handling | .catch() | Plain try/catch — the same as synchronous code |
| Debugging | Breakpoints are awkward, stacks are a mess | Step line by line, clean stacks |
| Intermediate values | Shared only by nesting or passing them along | Just ordinary local variables |
| Concurrency | Parallel by nature (build them, then all) | Easy to make serial by accident — the most common performance mistake there is |
That “serial by accident” trap is worth its own sentence: two requests that do not depend on each other, written as two await lines, turn into “wait for the first, then send the second”, so the total is the sum of both. Fire them both off first, then await Promise.all.
Follow-up: “When is .then still the better choice?” — for a single step with no intermediate values, or when you deliberately do not want to wait (fire and forget). .then also reads better when you are storing a Promise and passing it around.