C16. 异步编程 async/await
6.1. 🌟 async 标记的异步函数返回 Promise 对象
async
关键词将函数标记为“异步函数”,其返回值始终是一个Promise
对象。
javascript
// 普通函数 vs 异步函数对比
function normalFunc() {
return "普通结果"; // 直接返回值
}
async function asyncFunc() {
return "异步结果"; // 等价于 Promise.resolve("异步结果")
}
asyncFunc().then(result => console.log(result)); // "异步结果"
async 特性
- 自动包装返回值:任何返回值会被自动包裹为
Promise.resolve(value)
- 错误自动包装:函数内部抛出的错误会转为
Promise.reject(error)
- 只能在函数前使用:
async
仅修饰函数定义
6.2. ⭐ 异步函数中 await 表达式可直接获取 Promise 内部值
await
关键字暂停函数执行,直到Promise
完成,直接获取其成功值。
javascript
async function fetchData() {
const response = await fetch("https://api.example.com/data"); // 等待响应
const data = await response.json(); // 等待解析 JSON
console.log(data); // 直接使用数据
}
fetchData();
核心规则
await
只能在async
函数内使用- 暂停的是当前函数的执行,不会阻塞主线程
- 等待期间代码控制权返回浏览器
6.2.1. 简化 Promise 链式调用
javascript
// 传统 Promise 写法
fetch("https://api.example.com")
.then(response => response.json())
.then(data => console.log(data));
// async/await 写法
async function simplifiedFetch() {
const response = await fetch("https://api.example.com");
const data = await response.json();
console.log(data);
}
6.3. 🌟 await 将异常 Promise 对象直接抛出
如果
Promise
被拒绝(reject
),await
会抛出错误,需用try/catch
捕获。
javascript
async function errorDemo() {
try {
const response = await fetch("https://api.example.com/404");
if (!response.ok) throw new Error("HTTP错误"); // 自定义错误
const data = await response.json();
} catch (error) {
console.error("捕获到错误:", error.message); // 直接处理错误
}
}
errorDemo();
错误处理要点
- 必须用
try/catch
包裹可能出错的await
表达式 - 未捕获的
await
错误会冒泡到全局(如浏览器控制台报错) - 可以链式
catch
:javascriptmyAsyncFunc() .catch(error => console.log("最终错误处理"));
知识回顾
- 核心语法关系:
async
函数 → 返回Promise
await
解包Promise
的值或错误
- 关键特性:
- 代码更接近同步风格(避免嵌套
.then
) - 错误通过
try/catch
集中处理 - 保持非阻塞特性(不会卡住主线程)
- 代码更接近同步风格(避免嵌套
- 使用限制:
await
必须在async
函数内- 同步代码不能直接
await
- 陷阱提醒:
- 忽略错误处理导致程序崩溃
- 在循环中滥用
await
可能降低性能 Promise
链与async/await
可混合使用
课后练习
(单选)以下哪个是合法的 async 函数定义?
- A.
async function getData() { return fetch(...) }
- B.
function async getData() { ... }
- C.
await fetch("https://api.com");
(非函数内) - D. A和C都对
- A.
(填空)在 async 函数中,使用______关键字等待异步操作完成。
(代码纠错)修复以下代码,使错误被捕获:
javascriptasync function brokenFunc() { await fetch("https://invalid-url").then(data => console.log(data)); } // 错误:未处理网络错误
(操作题)重写 C15 中的 POST 表单提交案例,使用 async/await 替代 .then/catch:
- 显示加载状态
- 成功时显示“登录成功”
- 错误时显示具体提示(如网络问题/账号错误)
备注: (1) 通过对比传统 Promise 和 async/await 代码,突出语法优势 (2) 错误处理部分需强调 try/catch 的必要性 (3) 操作题要求综合运用 async/await 和 DOM 操作