Javascript 为什么.json()会返回一个承诺?

Javascript 为什么.json()会返回一个承诺?,javascript,asynchronous,promise,fetch-api,Javascript,Asynchronous,Promise,Fetch Api,我最近一直在玩弄fetch() let url = "http://jsonplaceholder.typicode.com/posts/6"; let iterator = fetch(url); iterator .then(response => { return { data: response.json(), status: response.status } }) .then(post =>

我最近一直在玩弄
fetch()

let url = "http://jsonplaceholder.typicode.com/posts/6";

let iterator = fetch(url);

iterator
  .then(response => {
      return {
          data: response.json(),
          status: response.status
      }
  })
  .then(post => document.write(post.data));
;
post.data
返回一个
Promise
对象。

但是,如果写为:

let url = "http://jsonplaceholder.typicode.com/posts/6";

let iterator = fetch(url);

iterator
  .then(response => response.json())
  .then(post => document.write(post.title));
;
iterator.then(response =>
    response.json().then(post => document.write(post.title))
);
post
这里有一个标准的
对象
,您可以访问title属性。


所以我的问题是:
response.json
为什么返回一个对象文本中的承诺,而如果刚刚返回,则返回值?

这种差异是由于承诺的行为而不是
fetch()

当一个
.then()
回调返回一个额外的
承诺时,链中的下一个
.then()
回调实质上绑定到该承诺,接收其解决方案或拒绝履行和价值

第二段也可以写成:

let url = "http://jsonplaceholder.typicode.com/posts/6";

let iterator = fetch(url);

iterator
  .then(response => response.json())
  .then(post => document.write(post.title));
;
iterator.then(response =>
    response.json().then(post => document.write(post.title))
);
在此表单和您的表单中,
post
的值由
response.json()
返回的承诺提供


但是,当您返回一个普通的
对象时,
.then()
会认为这是一个成功的结果,并立即自行解析,类似于:

iterator.then(response =>
    Promise.resolve({
      data: response.json(),
      status: response.status
    })
    .then(post => document.write(post.data))
);
在本例中,
post
只是您创建的
对象,它在其
数据
属性中持有
Promise
。等待这一承诺实现的过程仍然是不完整的

为什么
response.json
会返回承诺

因为一旦所有的头都到达,您就会收到
响应。调用
.json()
可以为尚未加载的http响应体获得另一个承诺。另见

如果我从
then
处理程序返回承诺,为什么要获取该值

因为。从回调中返回承诺并使其被采纳的能力是它们最相关的特性,它使它们无需嵌套即可链接

你可以用

fetch(url).then(response => 
    response.json().then(data => ({
        data: data,
        status: response.status
    })
).then(res => {
    console.log(res.status, res.data.title)
}));

或任何其他方法,以在等待json正文后获取响应状态。

除了上述答案之外,下面是如何处理来自api的500系列响应,其中您会收到json编码的错误消息:

function callApi(url) {
  return fetch(url)
    .then(response => {
      if (response.ok) {
        return response.json().then(response => ({ response }));
      }

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

let url = 'http://jsonplaceholder.typicode.com/posts/6';

const { response, error } = callApi(url);
if (response) {
  // handle json decoded response
} else {
  // handle json decoded 500 series response
}

另外,帮助我理解您描述的这个特定场景的是Promise API,特别是它解释了
then
方法返回的promised将如何根据处理程序fn返回的内容进行不同的解析:

如果处理程序函数:

  • 返回一个值,然后以返回的值作为其值解析返回的承诺
  • 抛出一个错误,然后返回的承诺被拒绝,抛出的错误作为其值
  • 返回一个已经解决的承诺,然后返回的承诺以该承诺的值作为其值得到解决
  • 返回一个已经被拒绝的承诺,然后返回的承诺将以该承诺的值作为其值被拒绝
  • 返回另一个挂起的承诺对象,此时返回的承诺的解决/拒绝将在 处理人返回的承诺的决议/拒绝。此外, 届时返回的承诺的价值将与 处理程序返回的承诺

我刚刚找到的另一个选项是:

  • const response=fetch(“url”)
  • const data=wait response.json()
  • 常量信息=等待数据

  • “Information”是最后一个响应:)

    将wait与response.json()一起使用

    const responce = await fetch(url);
    const result = await responce.json();
    

    <强>使用Acth.Acth.JSONE()和

    ,这是有意义的。当你考虑<代码>响应时,JSON()/<代码>承诺如果响应无效JSON会被拒绝。现在该值在then方法中可用。这是否回答了您的问题?请注意,尽管方法名为json(),但结果不是json。它返回一个promise,该promise使用JavaScript对象解析,该对象是将正文文本解析为JSON的结果。这个对象可以是任何可以用JSON表示的东西——一个对象、一个数组、一个字符串、一个数字。。。参考:这是迄今为止对我最有帮助的答案。我不能使用承诺等待数据返回,并且在数据到达时将其转换为json,这似乎很奇怪?或者在这种情况下,我可以使用
    JSON.parse()
    而不是
    res.JSON()
    ?@Kokodoko
    res.JSON()
    基本上是
    res.text()的快捷方式。然后(JSON.parse)
    。两者都使用承诺等待数据并解析json。@Bergi,你好,很抱歉我遇到了一些困惑,即使用then(res=>res.json())我们发送了另一个请求来获取json?@mirzhal否,没有其他请求。它只是读取(异步!)响应的其余部分。
    const responce = await fetch(url);
    const result = await responce.json();