Fetch 是用于发出网络请求的新的基于 Promise 的 API:
fetch('https://www.everythingisawesome.com/')
.then(response => console.log('status: ', response.status));
Run Code Online (Sandbox Code Playgroud)
这对我来说很有意义——当我们发起网络调用时,我们会返回一个 Promise,让我们的线程继续处理其他业务。当响应可用时,Promise 中的代码就会执行。
但是,如果我对响应的有效负载感兴趣,我会通过响应的方法而不是属性来这样做:
这些方法返回承诺,我不清楚为什么。
fetch('https://www.everythingisawesome.com/') //IO bound
.then(response => response.json()); //We now have the response, so this operation is CPU bound - isn't it?
.then(entity => console.log(entity.name));
Run Code Online (Sandbox Code Playgroud)
为什么处理响应的有效负载会返回一个承诺 - 我不清楚为什么它应该是一个异步操作。
zzz*_*Bov 11
为什么这些 fetch 方法是异步的?
天真的答案是“因为规范是这么说的”
当然,这并不能真正回答问题,因为它留下了“为什么规范这么说?”的问题。
这就是事情变得复杂的地方,因为我很确定这个推理,但我没有来自官方的证据来证明这一点。我将尝试尽我所能地解释其合理性,但请注意,此后的所有内容都应在很大程度上被视为外部意见。
当您使用 fetch API 向资源请求数据时,您必须等待资源下载完成才能使用它。这应该是相当明显的。JavaScript 使用异步 API 来处理此行为,以便所涉及的工作不会阻止其他脚本,更重要的是阻止 UI。
当资源下载完成后,数据可能会非常庞大。没有什么可以阻止您请求超过 50MB 的整体 JSON 对象。
如果您尝试同步解析 50MB 的 JSON,您认为会发生什么?它会阻止其他脚本,更重要的是阻止 UI。
其他程序员已经解决了如何以高效的方式处理大量数据:Streams。在 JavaScript 中,流是使用异步 API 实现的,因此它们不会阻塞,如果您阅读消费主体详细信息,很明显流正在用于解析数据:
如果 body 非空,则让 Stream 为 body 的流,否则为空 ReadableStream 对象。
现在,规范当然有可能定义两种访问数据的方式:一种用于较小量数据的同步 API,一种用于较大量数据的异步 API,但这会导致混乱和重复。
除此之外,你不需要它。一切可以用同步代码表达的东西都可以用异步代码表达。反之则不然。因此,创建了一个可以处理所有用例的异步API。
| 归档时间: |
|
| 查看次数: |
563 次 |
| 最近记录: |