await右侧表达式在await语句执行时立即求值,而非等待前一个await完成;例如fetch('/api/b')在const b = await fetch('/api/b')中仅当上一个await结束后才执行,属串行;并发需提前调用异步函数获取Promise。

在 async 函数中,await 表达式的求值顺序严格遵循从左到右的执行顺序,且每个 await 的右侧表达式(即 Promise 源)会在 await 语句执行时立即求值,而非等到前一个 await 完成后才开始计算。这是理解异步流程控制的关键细节,常被误认为“所有 await 都要等上一个结束才开始下一个”,其实不然。
await 右侧表达式在 await 语句执行时立即求值
JavaScript 引擎在遇到 await expr 时,会立刻对 expr 求值——这意味着函数调用、运算、变量读取等都会在此刻发生,无论 expr 是否返回 Promise。如果 expr 返回的是 Promise,await 才会暂停当前 async 函数,等待该 Promise settle;但如果 expr 是同步值(如数字、字符串或已 resolve 的 Promise),await 会立即继续。
例如:
async function f() {console.log('start');
const a = await slowFetch(1); // slowFetch(1) 立即调用
const b = await slowFetch(2); // slowFetch(2) 在 a 完成后才调用
return a + b;
}
这里 slowFetch(1) 在第一个 await 处立即执行,而 slowFetch(2) 要等到第一个 await 完全结束后才执行——因为它是下一条语句的右侧表达式。
立即学习“Java免费学习笔记(深入)”;
多个 await 连续写时,表达式不并行启动
下面这种写法不会并发发起请求:
const a = await fetch('/api/a');const b = await fetch('/api/b');
原因:第二行的 fetch('/api/b') 要等到第一行的 await 完全 resolve 后才执行。整个过程是串行的。
若想并发,需提前触发 Promise 构造:
- 先调用所有异步函数,得到 Promise 实例(此时请求已发出)
- 再用 await 分别等待它们
const promiseB = fetch('/api/b'); // 请求立即发出
const a = await promiseA;
const b = await promiseB;
await 表达式内部的嵌套求值也即时发生
await 的右侧可以是任意表达式,包括函数调用链、三元运算、解构等。这些子表达式都在 await 执行点完成求值。
例如:
await (condition ? apiCallX() : apiCallY());这里的三元判断和对应函数调用(apiCallX() 或 apiCallY())在 await 开始时就完成了——哪怕 condition 是个复杂计算,它也发生在 await 暂停之前。
再比如:
await getUser().then(x => x.profile).catch(err => defaultProfile);getUser() 立即调用;.then 和 .catch 的回调注册也立即完成;但实际的 profile 提取或错误处理逻辑,要等 Promise settle 后才运行。
参数计算时机与 await 无关,只取决于表达式位置
函数调用的参数总是在函数被调用时求值,与是否出现在 await 右侧无关。例如:
await fetch(url + '?t=' + Date.now());其中 url + '?t=' + Date.now() 在 fetch 被调用那一刻(即 await 执行时)计算,不是在 fetch 返回后。因此每次调用都带实时时间戳。
常见误区是以为“await 会推迟整个表达式”,其实它只推迟后续代码执行,不推迟自身右侧的求值。


















