### 一、`async` 的作用
1. **修饰函数声明**
- 正确:`async function foo() {}` 或 `const foo = async () => {}`
- **核心行为**:
- 函数返回值会被自动包装为 `Promise`
- 若返回值是普通值 → 转换为 `Promise.resolve(value)`
- 若返回值是 `Promise` → 直接返回该 Promise
- 示例:
```javascript
async function example() {
return 42; // 等效于 return Promise.resolve(42)
}
example().then(v => console.log(v)); // 输出 42
```
---
### 二、`await` 的行为
1. **作用对象**
- **不是修饰函数调用**,而是用于等待一个 `Promise` 的解决(resolve)或拒绝(reject)
- 可以放在任何返回 `Promise` 的表达式前(不一定是函数调用)
2. **核心机制**
- **暂停异步函数执行**:在 `await` 处暂停当前 `async` 函数的执行(但不会阻塞主线程)
- **解包 `Promise`**:提取 `Promise` 的 `resolve` 值
- **处理拒绝(reject)**:若 `Promise` 被拒绝,`await` 会抛出异常(可用 `try/catch` 捕获)
3. **示例分析**:
```javascript
async function demo() {
const result = await fetchData();
// 等效于:
// fetchData().then(result => { /* 后续代码 */ })
console.log(result);
}
```
---
### 三、关键区别与纠正
| 描述 | 修正说明 |
|---------------------------|--------------------------------------------------------------------------|
| "将 Promise 转为同步操作" | **不准确**:`await` 不会将异步变同步,只是让代码写法看似同步,底层仍异步 |
| "直接提取 resolve 的值" | **正确**:但需注意 `reject` 会抛出异常 |
| "使用 then 接收参数" | **可选方式**:但 `async` 函数内更推荐用 `await` 代替 `.then()` 链式调用 |
---
### 四、同步与异步的本质对比
**同步代码**:
```javascript
function syncExample() {
const a = doTaskA(); // 阻塞主线程直到完成
const b = doTaskB(a); // 必须等待 doTaskA 完成
return b;
}
```
**async/await 代码**:
```javascript
async function asyncExample() {
const a = await doTaskA(); // 暂停函数执行,但主线程可处理其他任务
const b = await doTaskB(a); // 看起来像同步,实际通过事件循环处理
return b;
}
```
---
### 五、典型错误示例
1. **误以为完全同步**:
```javascript
async function misleading() {
await delay(1000); // 暂停函数内代码,但主线程不阻塞
console.log("1秒后输出");
}
console.log("立即输出"); // 实际先执行此句
```
2. **忽略错误处理**:
```javascript
async function dangerous() {
const data = await fetchAPI(); // 若 API 返回 500 错误,会抛出异常
// 后续代码不会执行
}
```
---
### 六、正确使用模式
1. **组合 `async/await` 与 `try/catch`**:
```javascript
async function safeFetch() {
try {
const res = await fetch('https://api.example.com');
return res.json();
} catch (err) {
console.error("请求失败:", err);
throw err; // 可选择重新抛出
}
}
```
2. **并行优化**:
```javascript
async function parallel() {
const [user, orders] = await Promise.all([
fetchUser(),
fetchOrders()
]);
}
```
---
### 总结
- ✅ `async`:声明一个函数返回 `Promise`,其内部可使用 `await`
- ✅ `await`:暂停函数执行直到 `Promise` 完成,提取 `resolve` 值
- ❌ **误区**:`await` 不会让 JavaScript 变成同步语言,只是控制异步代码的编写方式
- ⚠️ **必须处理**:`await` 可能抛出的异常(通过 `try/catch` 或 `.catch()`)
理解这些机制后,可以更安全地编写看似同步、实则非阻塞的异步代码。