一、async/await 是什么?
async/await 是 ES2017(ES8)引入的异步编程语法糖,基于 Promise 实现,目的是让异步代码的写法更接近同步代码,降低阅读和编写成本。核心概念拆解:
- async 关键字
- 只能修饰函数(函数声明、函数表达式、箭头函数都可以)。
- 被 async 修饰的函数,返回值一定是 Promise 对象:
- 如果函数内部返回非 Promise 值(比如数字、字符串),会自动被包装成 resolve 状态的 Promise;
- 如果函数内部抛出错误,会返回 reject 状态的 Promise;
- 如果函数内部返回 Promise,则直接返回这个 Promise。
- await 关键字
- 只能在 async 函数内部使用,不能单独使用。
- 作用:等待右侧的 Promise 完成(状态变为 resolve 或 reject),并暂停当前 async 函数的执行,直到 Promise 有结果:
- 如果 Promise 是 resolve 状态,await 会返回 Promise 的成功值;
- 如果 Promise 是 reject 状态,await 会抛出错误,需要用 try/catch 捕获。
二、为什么要用 async/await?
核心原因:解决传统回调地狱、简化 Promise 链式调用的复杂度。我们通过对比来理解:场景:模拟异步请求(比如先请求用户信息,再根据用户 ID 请求订单)
1. 回调函数写法(回调地狱)
- // 模拟异步请求函数
- function getUserInfo(callback) {
- setTimeout(() => {
- callback(null, { id: 1, name: "张三" });
- }, 1000);
- }
- function getOrderByUserId(userId, callback) {
- setTimeout(() => {
- callback(null, { orderId: 1001, userId: userId });
- }, 1000);
- }
- // 调用:多层嵌套,代码臃肿,可读性差
- getUserInfo((err, user) => {
- if (err) return console.error(err);
- getOrderByUserId(user.id, (err, order) => {
- if (err) return console.error(err);
- console.log("订单信息:", order);
- });
- });
复制代码 2. Promise 写法(改善但仍有链式冗余)- function getUserInfo() {
- return new Promise((resolve) => {
- setTimeout(() => resolve({ id: 1, name: "张三" }), 1000);
- });
- }
- function getOrderByUserId(userId) {
- return new Promise((resolve) => {
- setTimeout(() => resolve({ orderId: 1001, userId: userId }), 1000);
- });
- }
- // 调用:链式调用,比回调好,但仍有.then 嵌套,逻辑不连贯
- getUserInfo()
- .then(user => getOrderByUserId(user.id))
- .then(order => console.log("订单信息:", order))
- .catch(err => console.error(err));
复制代码 3. async/await 写法(简洁如同步)- function getUserInfo() {
- return new Promise((resolve) => {
- setTimeout(() => resolve({ id: 1, name: "张三" }), 1000);
- });
- }
- function getOrderByUserId(userId) {
- return new Promise((resolve) => {
- setTimeout(() => resolve({ orderId: 1001, userId: userId }), 1000);
- });
- }
- // 核心:async 函数 + await 等待异步结果
- async function getOrderInfo() {
- try {
- // 等待 getUserInfo 完成,拿到用户信息(同步写法)
- const user = await getUserInfo();
- // 等待 getOrderByUserId 完成,拿到订单信息
- const order = await getOrderByUserId(user.id);
- console.log("订单信息:", order);
- } catch (err) {
- // 统一捕获所有异步错误
- console.error(err);
- }
- }
- // 执行函数
- getOrderInfo();
复制代码 三、async/await 的核心优势
- 代码可读性极高:异步逻辑按 “从上到下” 的同步顺序书写,无需嵌套或链式调用,新手也能快速理解。
- 错误处理更统一:用 try/catch 捕获所有异步错误(包括 Promise 的 reject),替代 Promise 的多个 .catch。
- 调试更友好:可以像同步代码一样打断点,逐行调试(Promise 链式调用调试时难以追踪执行顺序)。
- 支持顺序 / 并行执行:
- 顺序执行:如上例,await 依次等待,适合依赖前一个结果的场景;
- 并行执行:如果异步操作无依赖,可先用变量存储 Promise,再一起 await,提升性能:
- async function getMultiData() {
- // 先创建两个 Promise(立即执行异步操作)
- const userPromise = getUserInfo();
- const orderPromise = getOrderByUserId(1); // 假设 ID 已知,无需等用户信息
- // 并行等待两个 Promise 完成
- const [user, order] = await Promise.all([userPromise, orderPromise]);
- console.log(user, order);
- }
复制代码 总结
- async/await 是 Promise 的语法糖,不改变异步本质,只是让异步代码写法更简洁;
- async 修饰函数,使其返回 Promise;await 只能在 async 函数内使用,等待 Promise 结果并暂停函数执行;
- 核心价值:解决回调地狱、简化 Promise 链式调用,让异步代码的阅读 / 编写 / 调试成本大幅降低。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |