JavaScript 的 fetch API 广泛用于发出 HTTP 请求,但理解为什么它有时需要两个 wait 语句可能有点棘手。如果您以前使用过 fetch,您可能遇到过如下代码:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
登录后复制
登录后复制
让我们分解一下并理解为什么这种模式是必要的。 ?
获取的两步过程?️
fetch API 旨在异步处理网络请求,但其行为分为两个主要阶段:
-
获取响应 ?
- 当你调用 fetch 时,它会返回一个 Promise,一旦网络请求完成,该 Promise 就会解析为 Response 对象。
- 此步骤不处理响应正文;它仅确保请求成功并且标头可用。
-
阅读响应正文 ?
- Response 对象具有 .json()、.text() 和 .blob() 等方法来读取实际内容。
- 这些方法还返回 Promises,因为读取正文是异步的。这是有效处理大型负载而不阻塞主线程所必需的。
第一次等待期间会发生什么? ⏳
当您编写 const response = wait fetch(url); 时,会发生以下情况:
-
已发送网络请求: ?
- 浏览器向指定的URL发起HTTP请求。
- 这涉及解析域名、建立 TCP 连接以及发送 HTTP 标头和正文(对于 POST 请求)。
-
收到响应元数据: ?
- 一旦服务器响应状态行(例如,HTTP/1.1 200 OK)和标头,提取调用就会解析。在此刻:
- 状态(例如 200、404 或 500)和状态文本(例如“确定”或“未找到”)可用。
- 响应标头(例如 Content-Type、Content-Length)以及服务器发送的任何自定义标头都是可访问的。
-
已创建响应对象: ?️
- 浏览器构造一个 Response 对象,其中包含有关响应的元数据。这包括:
-
标头:可通过response.headers访问,它允许您检查特定标头,例如内容类型或授权。
-
正文: 此时,正文尚未完全读取或解析 - 它仍然是可读流。
例如,如果服务器返回:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 123
{"message": "Hello, world!"}
登录后复制
响应对象将包含:
-
状态:200 ✅
-
状态文本:“确定”✅
-
headers:响应头的可迭代集合(例如,Content-Type:application/json)。
-
body:尚未解析的可读流。
第二次等待期间会发生什么? ?
当您编写 const data = wait response.json(); 时,会发生以下步骤:
-
身体流阅读: ?
- 响应正文(仍为原始形式)作为流读取。根据您使用的方法,原始数据会进行相应的处理:
-
.json():将流解析为 JSON 并返回 JavaScript 对象。
-
.text():将流读取为纯文本字符串。
-
.blob():将流读取为二进制大对象。
-
解析和解析: ?
- json() 方法将原始数据(例如,{"message": "Hello, world!"})解析为可用的 JavaScript 对象(例如,{ message: "Hello, world!" })。
- 此解析过程是异步的,因为它涉及处理潜在的大数据。
-
承诺决议: ✅
- response.json() 返回的 Promise 解析为解析后的数据,然后可以在您的应用程序中使用该数据。
为什么需要两个await语句?
这是您需要等待两次的原因:
-
首先等待(等待响应):
- fetch 调用不会立即提供响应数据;它给了你一个承诺。您需要等待它才能获取 Response 对象。
-
第二次等待(解析正文):
- .json() 方法(或其他正文读取方法)返回另一个 Promise。您需要等待此操作才能提取解析的内容。
如果您跳过任一等待,您可能会出现意想不到的行为:
-
跳过第一个等待:您将使用未解决的 Promise,而不是实际的 Response 对象。
-
跳过第二个等待:你将得到一个 Promise,而不是解析后的数据。
错误处理示例?️
以下是在使用 fetch 时正确处理错误的方法:
const response = await fetch('https://api.example.com/data');
const data = await response.json();
登录后复制
登录后复制
常见陷阱⚠️
-
不处理错误:
-
fetch 不会抛出 404 或 500 等 HTTP 错误。您必须手动检查 response.ok 或 response.status。
-
跳过第二个等待:
- 忘记等待 .json() 可能会导致您使用 Promise 而不是实际数据时出现错误。
-
fetch 和旧版 API 之间的混淆:
- 从 XMLHttpRequest 等旧 API 过渡的开发人员可能期望同步行为,但 fetch 完全基于 Promise。
结论 ?
在 fetch 中使用两个await语句乍一看似乎有些多余,但这是其异步设计的逻辑结果。第一个等待确保已收到响应,包括标头和元数据,而第二个等待处理响应正文。了解此流程有助于您编写更可靠且可维护的异步代码。 ?
以上是理解为什么 Fetch 需要等待两次✨的详细内容。更多信息请关注PHP中文网其他相关文章!