红宝书第十八讲:详解JavaScript的async/await与错误处理


红宝书第十八讲:详解JavaScript的async/await与错误处理

资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲


一、async/await的作用:让异步代码"看起来"同步

async/await 是Promise的语法糖,可以让异步代码像同步代码一样直白。核心规则:

  • async :声明一个函数是异步的,函数内可用await
  • await :等待一个Promise完成,并返回其结果 ^1^^2^
示例:对比Promise与async/await
javascript 复制代码
// Promise链式调用
function fetchDataPromise() {
  fetch('/api/data')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('请求失败:', error));
}

// async/await改写 → 更像同步代码
async function fetchDataAsync() {
  try {
    const response = await fetch('/api/data'); // 等待fetch完成
    const data = await response.json(); // 等待JSON解析
    console.log(data);
  } catch (error) {
    console.error('请求失败:', error); // 集中错误处理
  }
}

^[1](#1: 资料1指出async函数需用await等待异步操作 "#user-content-fn-1")^: 资料1指出async函数需用await等待异步操作
^[2](#2: 资料3展示await等待Promise的结果并继续执行 "#user-content-fn-3")^: 资料3展示await等待Promise的结果并继续执行


二、错误处理:用try/catch捕获异步错误

调用async函数返回的是Promise,可以通过两种方式处理错误:

  1. 内部try/catch:直接在async函数内捕获异常
  2. 外部.catch():像普通Promise一样链式处理
示例1:内部try/catch
javascript 复制代码
async function loadData() {
  try {
    const data = await fetchApi(); // 假设fetchApi返回Promise
    return processData(data);
  } catch (error) {
    console.error('加载失败:', error);
    return null; // 返回兜底值
  }
}
示例2:外部.catch()(适合链式调用)
javascript 复制代码
loadData()
  .then(result => console.log('结果:', result))
  .catch(error => console.error('外部捕获:', error));

^[3](#3: 资料5显示,若async函数内抛出错误会被catch()捕获 "#user-content-fn-5")^: 资料5显示,若async函数内抛出错误会被catch()捕获


三、执行流程解析

async/await流程图

  1. 遇到await暂停执行,交出线程控制权
  2. Promise完成后 → 恢复执行后续代码
  3. 若Promise被拒绝 → 触发catch或try/catch块
flowchart TD start[调用async函数] --> 执行同步代码 执行同步代码 --> 遇到await 遇到await --> 等待Promise结果 等待Promise结果 -->|成功| 提取结果并继续 等待Promise结果 -->|失败| 触发catch或try/catch 提取结果并继续 --> 执行后续代码

四、重点注意事项

  1. await只能在async函数内使用

    javascript 复制代码
    // 错误示例!
    function normalFunc() {
      const data = await fetchData(); // 报错:await需在async函数中
    }
  2. async函数返回的是一个Promise

    javascript 复制代码
    async function foo() { return 5; }
    foo().then(value => console.log(value)); // 输出5
  3. 错误需要主动捕获,否则可能导致未处理的Promise拒绝

    javascript 复制代码
    async function riskyTask() {
      throw new Error('危险操作');
    }
    // 正确做法:用try/catch或.catch()
    riskyTask().catch(e => console.log('错误已处理:', e));

^[3](#3: 资料5强调未捕获的异步错误会导致Uncaught Promise Rejection "#user-content-fn-5")^: 资料5强调未捕获的异步错误会导致Uncaught Promise Rejection


五、综合应用:并行请求与错误隔离

javascript 复制代码
async function fetchMultipleData() {
  try {
    // 同时发起多个请求(并行)
    const [user, posts] = await Promise.all([
      fetch('/api/user'),
      fetch('/api/posts')
    ]);

    // 处理结果
    const userData = await user.json();
    const postsData = await posts.json();
    return { userData, postsData };
  } catch (error) {
    console.error('有请求失败:', error);
    throw error; // 可选择重新抛出错误供外部处理
  }
}

// 调用
fetchMultipleData()
  .then(data => console.log('全部成功:', data))
  .catch(() => console.log('外部处理失败'));

[^4]: 资料4提供并行请求的错误处理思路


目录:总目录 上篇文章:红宝书第十七讲:通俗详解JavaScript的Promise与链式调用

脚注

Footnotes

  1. 《JavaScript高级程序设计(第5版)》中解释async函数声明方式 2

  2. 《JavaScript高级程序设计(第5版)》显示await等待Promise结果并解包 2

  3. 《JavaScript高级程序设计(第5版)》说明throw在async函数内会被转换为拒绝的Promise 2

相关推荐
Moment20 分钟前
Next.js 15.4 正式发布:Turbopack 全面稳定,预热 Next.js 16 😍😍😍
前端·javascript·node.js
虚!!!看代码25 分钟前
uni-app 跳转页面传参
前端·vue.js·uni-app
脑袋大大的35 分钟前
UniApp 自定义导航栏:解决安全区域适配问题的完整实践
前端·javascript·安全·uni-app·uniapp·app开发·uniappx
这辈子谁会真的心疼你39 分钟前
pdf格式怎么提取其中一部分张页?
前端·pdf
人工智能训练师1 小时前
Tailwind CSS中设定宽度和高度的方法
前端·css·css3
csdn_aspnet1 小时前
在 .NET Core 中创建 Web Socket API
javascript·websocket·.netcore
csdn_aspnet2 小时前
在 ASP.NET Core 和 JavaScript 中配置 WebSocket
javascript·ecmascript·.netcore
Kiri霧2 小时前
Kotlin比较接口
android·java·前端·微信·kotlin
LinXunFeng2 小时前
Flutter - 聊天面板库动画生硬?这次让你丝滑个够
前端·flutter·github
Lanwarf-前端开发2 小时前
turbo-monorepo中自定义脚本运行项目下的包
javascript