DrillLab
第 40 / 105 道40 / 105 · #306

async/await vs Promise

Async/await vs Promise

先自己答,再往下看Answer it yourself first

一句话: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() chainasync/await
ReadabilityHard to follow the moment it nestsLinear, easy to read
Error handling.catch()Plain try/catch the same as synchronous code
DebuggingBreakpoints are awkward, stacks are a messStep line by line, clean stacks
Intermediate valuesShared only by nesting or passing them alongJust ordinary local variables
ConcurrencyParallel 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.

JavaScriptasync/await 最常见的性能错误The most common performance mistake with async/await示意Illustrative
1// ✗ 串行:总耗时 = a + b
2const user = await fetchUser(); // 等 200ms
3const posts = await fetchPosts(); // 再等 200ms -> 共 400ms
4
5// ✓ 并行:总耗时 = max(a, b)
6const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
7// ↑ 两个请求同时发出去 -> 共 200ms
8
9// 有依赖时串行才是对的
10const user = await fetchUser();
11const posts = await fetchPosts(user.id); // 必须先有 user.id
1// ✗ One after the other: total time = a + b
2const user = await fetchUser(); // wait 200ms
3const posts = await fetchPosts(); // wait another 200ms -> 400ms in total
4
5// ✓ Side by side: total time = max(a, b)
6const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
7// ↑ both requests go out at once -> 200ms total
8
9// When one depends on the other, going one at a time is correct
10const user = await fetchUser();
11const posts = await fetchPosts(user.id); // user.id has to exist first