为啥 Body.json() 返回一个 Promise? [复制]
Posted
技术标签:
【中文标题】为啥 Body.json() 返回一个 Promise? [复制]【英文标题】:Why does Body.json() return a Promise? [duplicate]为什么 Body.json() 返回一个 Promise? [复制] 【发布时间】:2018-06-01 15:11:37 【问题描述】:我从 JS 开始,实际上喜欢异步方面(来自 Python),但我不确定为什么有些函数会返回 Promise。具体来说,下面使用fetch
的代码让我想知道json()
返回了什么:
fetch('https://freegeoip.net/json/8.8.8.8')
.then((response) =>
return response.json()
)
.then((json) =>
Object.keys(json).forEach((key) =>
console.log("got " + key)
)
)
抛开流式传输不谈,我们在GET
之后得到的 HTTP 响应是一个文本块,随后客户端会对其进行解释以提取标题、正文和其他有趣的元素 - 作为 HTTP 内容分析的一部分。
重点是这段文字是一体的,所以第一个then()
已经有了完整的响应——为什么解析JSON体是一个异步操作,和第二个@中的forEach
不同987654327@?
换句话说,为什么我不能让下面的代码工作?
fetch('https://freegeoip.net/json/8.8.8.8')
.then((response) =>
Object.keys(response.json()).forEach((key) =>
console.log("got " + key)
)
)
注意:如果第一个代码运行不正确(使用ERR_BLOCKED_BY_CLIENT
),请尝试禁用您的广告拦截器。第二个是故意不正确的。
【问题讨论】:
"我们在 GET 之后得到的 HTTP 响应是一个文本块" - 不。这是一个流。 @Bergi:在这种情况下,一切都是流(数据包、字节等)。GET
将一个已完成的文本块合并为一个片段(除了真正的流式传输,数据流不会结束)。同样,不能谈论“将文件读入内存”,因为它在技术上是流式传输。
流式传输的要点在于它可以带来多个文本块——例如,可以在正文尚未完成时已经处理标题。这正是这里发生的事情。
【参考方案1】:
您的第二个 sn-p 不起作用,因为 response.json()
aka body.json()
不会立即解决。
这是因为 body.JSON()
streams
和 returns
和 Response
异步使用了 Promise
;然后必须由then()
回调捕获,以便读取/操作。
这就是Promises
的本质。
然而,这样的句法流仍然可以通过利用async
await
来实现。
fetch('https://freegeoip.net/json/8.8.8.8')
.then(async (response) =>
Object.keys(await response.json()).forEach((key) =>
console.log("got " + key)
)
)
【讨论】:
【参考方案2】:你是对的 - 两个 sn-ps 都做同样的事情。在第一个 sn-p 中,以下部分:
.then((response) =>
return response.json()
)
只是在第一步中处理响应并传递结果。这个简单的案例不需要分成两个步骤,所以你可以很容易地使用第二个例子。
在某些情况下它可能很有用。
【讨论】:
以上是关于为啥 Body.json() 返回一个 Promise? [复制]的主要内容,如果未能解决你的问题,请参考以下文章