async/await 不改变同步代码执行节奏,仅暂停所在 async 函数,不阻塞主线程;混用常见错误包括误以为 await 控制全局顺序、非 async 函数内不 await 调用、同步逻辑未等待异步结果。

async/await 本身不会让同步代码变异步,也不会把异步代码“拉回”同步节奏——混用时真正危险的,是误以为 await 能控制外部执行流,而忽略了它只暂停自身函数、不阻塞主线程这一本质。
同步代码照常跑,await 只管自己家的门
同步语句(如 console.log、变量赋值、循环)永远在当前调用栈里立刻执行;await 只会让它所在的 async 函数暂停,然后主线程继续往下走。比如:
-
console.log('A')→ 立即输出 -
await fetch('/api')→ 当前 async 函数挂起,但 JS 引擎马上去执行后续同步代码 -
console.log('B')→ 不等请求回来,立刻输出
混用时最典型的三类错位
1. 以为写了 await,整个脚本就“按顺序等完了再往下”
错:await 不影响函数外的代码。下面这段里,other() 和 fetch 是并行发起的:
async function main() {
await fetch('/user');
console.log('done');
}
main();
other(); // 这行立刻执行,不等 'done'
2. 在非 async 函数里直接调用 async 函数却不 await
错:这等于只启动了 Promise,没等结果,返回的是 pending 状态的 Promise 对象,后续逻辑可能读到 undefined:
-
const data = getUser();→ data 是 Promise,不是用户数据 - 若后续写
data.name,会报错
3. 同步逻辑依赖异步结果,却没做等待或兜底
例如渲染页面前需要用户权限,但权限获取用了 async,而渲染函数是纯同步的:
- 没等权限就 render → 渲染出空或错误内容
- 正确做法:把 render 也包进 async 函数,或用 .then 链式衔接
安全混用的两个硬规则
- 边界必须清晰:同步代码不跨 await 获取异步结果;要取结果,就得在同一个 async 函数里 await,或用 then/catch 接续
- 调用链必须贯通:只要某处用了 async/await,上游调用者要么也声明 async 并 await,要么用 Promise 方法处理返回值;不能“半截子 async”
调试时一眼识别顺序问题
加时间戳和标记打印,比猜更可靠:
console.log(`${Date.now()} [sync] start`);
await fetch('/api');
console.log(`${Date.now()} [async] done`);
console.log(`${Date.now()} [sync] continue`);
输出顺序能清楚暴露:哪段真同步、哪段被跳过、哪段延迟执行。











