async和await的基本用法解析

有没有人在啊,想请说明下,async和await的基本用法解析
最新回答
下一站↘婞諨

2026-07-23 11:30:25

async/await 是基于 Promise 的语法糖,用于简化异步操作写法,使代码更接近同步风格,提升可读性和可维护性。其核心用法包括声明异步函数、使用 await 暂停执行、结合 try...catch 处理错误,并通过 Promise.all() 实现并发请求。

1. 基本语法与核心机制
  • async 函数声明:通过 async 关键字定义函数,该函数始终返回一个 Promise 对象。
  • await 表达式:仅在 async 函数内部使用,用于暂停执行直到 Promise 解析完成,并返回解析值。若 Promise 被拒绝(reject),则抛出错误。
  • 与 Promise 的关系:async/await 是 Promise 的语法糖,底层仍依赖 Promise 的链式调用,但避免了嵌套的 .then() 和 .catch(),代码更简洁。

示例代码:

async function fetchData() { try { const response = await fetch('
https://api.example.com/data'
); const data = await response.json(); return data; } catch (error) { console.error('Error fetching data:', error); throw error; // 重新抛出错误 }}fetchData() .then(data => console.log('Data:', data)) .catch(error => console.error('Caught error:', error));
  • 代码解析:

    async function fetchData() 定义异步函数。

    await fetch() 暂停执行,直到请求完成。

    await response.json() 解析响应数据。

    try...catch 捕获异步操作中的错误,并通过 throw error 将错误传递给调用者。

2. 并发请求与 Promise.all()
  • 问题场景:多个独立异步请求需同时执行时,串行调用(如循环中直接使用 await)会导致效率低下。
  • 解决方案:使用 Promise.all() 并发执行多个 Promise,仅在所有请求成功时解析,或任一请求失败时拒绝。

示例代码:

async function fetchMultipleData() { try { const [data1, data2] = await Promise.all([ fetch('
https://api.example.com/data1'
).then(res => res.json()), fetch('
https://api.example.com/data2'
).then(res => res.json()) ]); console.log('Data 1:', data1); console.log('Data 2:', data2); return { data1, data2 }; } catch (error) { console.error('Error fetching multiple data:', error); throw error; }}fetchMultipleData() .then(result => console.log('Result:', result)) .catch(error => console.error('Caught error:', error));
  • 代码解析:

    Promise.all() 接收 Promise 数组,并发执行所有请求。

    解析结果以数组形式返回,可通过解构赋值获取各请求数据。

    任一请求失败时,Promise.all() 直接拒绝,触发 catch 块。

3. 错误处理最佳实践
  • try...catch 包裹:每个 await 表达式应位于 try...catch 块中,或通过顶层 try...catch 集中处理。
  • 重新抛出错误:在 catch 块中,使用 throw error 保留原始错误堆栈,避免 throw new Error(error.message) 丢失上下文。
  • 自定义错误类:通过继承 Error 定义自定义错误类型,便于区分错误来源。

示例代码:

class CustomError extends Error { constructor(message, code) { super(message); this.name = 'CustomError'; this.code = code; }}async function processData() { try { const data = await fetchData(); if (!data) { throw new CustomError('Data is empty', 404); } } catch (error) { if (error instanceof CustomError) { console.error('Custom error:', error.message, error.code); } else { console.error('Unexpected error:', error); } }}4. 循环中的 async/await
  • 串行执行(低效):直接在循环中使用 await 会导致每次迭代等待前一次完成,延长总执行时间。
  • 并行执行(推荐):通过 Promise.all() 结合 map 方法,将循环中的异步操作转换为并发执行。

示例代码:

// 串行执行(不推荐)async function processItemsSerial(items) { for (const item of items) { const result = await processItem(item); // 每次迭代等待完成 console.log('Result:', result); }}// 并行执行(推荐)async function processItemsParallel(items) { try { const results = await Promise.all(items.map(async item => { return await processItem(item); // 并发执行 })); console.log('Results:', results); return results; } catch (error) { console.error('Error processing items:', error); throw error; }}5. 性能考量与优化建议
  • 额外开销:Async 函数返回的 Promise 对象会带来轻微内存和计算成本。
  • 微任务队列延迟:Async/await 基于微任务队列,可能影响实时性要求高的场景。
  • 优化策略:

    避免不必要的 async 函数(如无 await 时直接使用 Promise)。

    对计算密集型任务使用 Web Workers 分流。

    减少冗余的 Promise 创建和解析步骤。

总结:async/await 通过同步风格的语法简化了异步编程,但需合理使用以避免性能陷阱。掌握其与 Promise 的关系、并发处理、错误管理及循环优化,能显著提升代码质量和执行效率。