结论先给一句话:
async / await并不是把异步变成同步,而是用“同步写法”来写“异步代码”,本质仍然是异步。
下面我从执行方式、事件循环、性能、使用意义、对比示例一步一步讲清楚。
一、最核心的区别一句话版
| 方式 | 本质 |
|---|---|
| 同步代码 | 阻塞线程,一步不完成,后面不执行 |
async + await | 不阻塞线程,遇到await会“暂停当前函数”,把控制权交回事件循环 |
JavaScript只有一条主线程,真正的“同步等待”在 JS 里几乎是不存在的(除非你卡死浏览器)。
二、执行层面到底发生了什么?
1. 同步方式(阻塞)
function syncTask() { const result = heavyCompute(); // 假设是耗时操作 console.log(result); console.log('end'); }执行流程:
heavyCompute 完成 → console.log(result) → console.log('end')
问题:
浏览器/UI 会卡死
JS 主线程被占用
用户无法点击、滚动
2. async / await(非阻塞)
async function asyncTask() { const result = await fetch('/api/data'); console.log(result); console.log('end'); }真实执行流程是:
调用 asyncTask ↓ 遇到 await ↓ 当前 asyncTask 暂停 ↓ JS 主线程继续执行其他任务 ↓ Promise resolved ↓ asyncTask 恢复执行JS 并没有“等在那里”
三、用事件循环角度看区别(重点)
示例对比
console.log('start'); async function test() { console.log('a'); await Promise.resolve(); console.log('b'); } test(); console.log('end');实际输出顺序是:
start a end b
为什么?
await后面的代码会被放进微任务队列当前同步栈执行完后才继续
await = Promise.then 的语法糖
四、async / await 和 Promise.then 本质是一样的
async / await 写法
async function getData() { const res = await fetch(url); const data = await res.json(); return data; }等价 Promise 写法
function getData() { return fetch(url) .then(res => res.json()) .then(data => data); }区别不在执行方式,在“可读性”
五、那 async / await 的“意义”到底是什么?
1. 让异步代码像同步一样“好读”
对比感受一下:
Promise 地狱版本
getUser() .then(user => { return getOrders(user.id); }) .then(orders => { return getOrderDetail(orders[0].id); }) .then(detail => { console.log(detail); }) .catch(err => console.error(err));async / await 版本
async function run() { try { const user = await getUser(); const orders = await getOrders(user.id); const detail = await getOrderDetail(orders[0].id); console.log(detail); } catch (e) { console.error(e); } }逻辑是线性的,但执行仍是异步的
2. 错误处理更像同步代码
try { const res = await fetch(url); } catch (err) { console.error(err); }比.catch():
更直观
不容易漏掉异常
更接近传统语言(Java / Python)
3. 更容易做流程控制
if (needLogin) { await login(); } await loadData(); await renderPage();不用嵌套、不用链式调用。
六、async / await 并不能解决什么问题?
1. 不能提升性能
await task1(); await task2();等价于串行
如果想并行:
await Promise.all([task1(), task2()]);2. 不能变成真正同步
JS 里不存在:
const data = fetchSync(url); //
如果有,浏览器会直接卡死。
七、什么时候“看起来像同步”但不是同步?
误区示例
const data = await fetch(url);
很多人以为:
“这一行执行完才会执行下一行,所以是同步”
❌ 错
✅ 正确理解是:
函数暂停
主线程继续
不是阻塞等待
八、一句话总结(面试可用)
async / await 的本质是 Promise 的语法糖,它不会阻塞主线程,只是让异步代码拥有同步的书写和阅读体验,真正的执行仍然依赖事件循环。