为什么Body.json()会返回一个Promise?

时间:2017-12-19 08:19:47

标签: javascript json promise fetch-api

我从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在第二个then()

换句话说,为什么我不能使用以下代码?

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),请尝试停用您的广告拦截器。第二个是故意不正确的。

2 个答案:

答案 0 :(得分:3)

您的第二个代码段不起作用,因为response.json()又名body.json()并未立即解决。

这是因为body.JSON() streamsreturnsResponse异步使用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)
  })
})

答案 1 :(得分:0)

你是对的 - 两个片段都是一样的。在第一个片段中,请参阅以下部分:

.then((response) => {
  return response.json()
})

只是在第一步处理响应并通过结果。这个简单的案例不需要将其分为两个步骤,因此您可以轻松使用第二个示例。

在某些情况下它可能很有用。