LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

【JavaScript】了解为什么Fetch有时候需要两次 await

admin
2024年12月28日 23:21 本文热度 31

在 JavaScript 中,fetch API 是一种常见的 HTTP 请求工具,但其需要两次 await 的机制可能让初学者感到疑惑。本文将通过示例与解析,理解这一特性。


基础示例

const response = await fetch('https://api.example.com/data');
const data = await response.json();

上面的代码为什么需要两次 await

Fetch 的两阶段流程

1. 获取响应

调用 fetch 时,它返回一个 Promise,在网络请求完成后解析为 Response 对象:

  • 仅获取元数据:此时只获取响应头信息,正文尚未处理。

2. 解析响应正文 📄

Response 对象包含的方法(如 .json().text())用于读取正文,这些方法返回另一个 Promise,因为读取和解析正文是异步操作。


第一次 await 的内部流程

当你执行以下代码:

const response = await fetch(url);

1. 发送请求

浏览器向指定 URL 发起网络请求:

  • 解析域名
  • 建立 TCP 连接
  • 发送 HTTP 请求

2. 接收响应元数据

  • 服务器返回状态行(如 HTTP/1.1 200 OK)和响应头后,fetch 的 Promise 解析。
  • 此时,你可以获取:
    • 状态码:如 200404
    • 状态文本:如 "OK""Not Found"
    • 响应头:如 Content-Type: application/json

3. 构造 Response 对象

  • 包含元数据的 Response 对象被创建:
    • Headers:通过 response.headers 获取。
    • Body:正文仍是未处理的可读流。

第二次 await 的内部流程

当你执行以下代码:

const data = await response.json();

1. 读取正文流

Response 对象的正文被解析为流:

  • .json():解析为 JSON 并返回 JavaScript 对象。
  • .text():读取为纯文本字符串。
  • .blob():读取为二进制大对象。

2. 异步解析

  • 流数据被解析为可用内容(如 { message: "Hello, world!" })。
  • 解析过程可能处理大数据,因此是异步的。

3. 返回解析结果

  • response.json() 返回的 Promise 解析为解析后的数据,可用于程序逻辑。

为什么需要两次 await

两次 await 是 Fetch 的设计逻辑,分别解决以下问题:

  1. **第一次 await**:

    • 等待网络请求完成,获取 Response 对象(包含状态码、头信息等元数据)。
  2. **第二次 await**:

    • 异步读取和解析响应正文,确保数据可用。

如果跳过任意一次 await 会如何?

  • **跳过第一次 await**:
    • 你将得到一个未解析的 Promise,而非 Response 对象。
  • **跳过第二次 await**:
    • 你将得到未解析的 Promise,而非解析后的数据。

完整示例:带错误处理

以下是一个完整的示例,展示如何正确处理错误:

try {
  const response = await fetch('https://api.example.com/data');
  
  if (!response.ok) {
    throw new Error(`HTTP error! Status: ${response.status}`);
  }
  
  const data = await response.json();
  console.log(data);
catch (error) {
  console.error('Error fetching data:', error);
}

错误处理注意点:

  1. **检查 response.ok**:fetch 不会对 HTTP 错误(如 404 或 500)抛出异常。
  2. 捕获解析错误:如果响应正文不符合预期格式(如 JSON 格式错误),解析时也会抛出异常。

常见问题与解决方案

1. 忘记错误处理

  • 问题fetch 默认不会对 HTTP 错误抛出异常,可能导致你误以为请求成功。
  • 解决:手动检查 response.ok 或 response.status

2. 忘记第二次 await

  • 问题:会导致代码处理未解析的 Promise,而非实际数据。
  • 解决:始终 await 解析方法(如 .json())。

3. 旧 API 的影响

  • 问题:从 XMLHttpRequest 等同步 API 迁移的开发者可能预期同步行为。
  • 解决:理解并适应 fetch 的 Promise 异步设计。

总结

使用 Fetch API 时,两次 await 是其异步设计的结果:

  1. **第一次 await**:确保接收到响应元数据。
  2. **第二次 await**:解析响应正文,获取最终数据。

理解 Fetch 的工作机制能帮助你编写更高效、可靠的异步代码!


阅读原文:原文链接


该文章在 2024/12/30 14:37:42 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved