我能以某种方式在第一个“then”中获得 fetch 响应吗?

Posted

技术标签:

【中文标题】我能以某种方式在第一个“then”中获得 fetch 响应吗?【英文标题】:Can I somehow get the fetch response in the first `then`? 【发布时间】:2019-02-04 15:30:05 【问题描述】:

我正在尝试使用 Fetch API。从示例看来,GET 请求需要一个then 以某种方式解析响应。

目前我正在这样做

fetch(url)
    .then(response => response.json())
    .then(response => 
        console.log(response);  
    );

但是,第一个 then 似乎是样板文件。我试图避免它,例如:

fetch(url)
    .then(response => 
        console.log(response.json());  
    );

但这会记录我一个待处理的Promise,状态为resolved

我阅读了有关此主题的其他问题并阅读了一些有关承诺的内容,但我不明白是否可以将其合并到一个 then 中(如果可以,如何?)。

例如,here 的两个答案指出

没有必要使用多个'.then'

没有充分的理由拥有两个 .then() 处理程序,因为每个处理程序的代码都可以合并到一个 .then() 处理程序中

但我无法让这个例子真正起作用——我仍然得到了一个承诺:)

相反,被接受的anwser here 解释说.then 实际上对结果做了一些事情(从promise 中提取返回值),但如果我自己能以某种方式做到这一点,我无法理解,比如response.json().then()response.json().getVal() 或双then 语法是唯一的方法。

【问题讨论】:

【参考方案1】:

这很简单:当您发送fetch() 请求时,它会返回一个包含响应的promise。这由第一个.then() 解决。解决第一个承诺实际上返回Response

现在这是棘手的部分:读取响应正文的方法,无论是 .json().text().blob()....所有返回承诺。这意味着您需要解析第二个 Promise 才能获得解析后的响应。

流程如下所示:

    发出fetch() 请求,它返回Response 类型的Promise 当你尝试解析Response的内容时,它会返回第二个Promise,它的类型取决于你使用的方法(例如.json()返回一个对象,.text()返回字符串,.blob()返回Blob) . 解决第二个 Promise,您将获得实际解析的响应正文

p/s:如果您没有在***上下文中使用fetch()(在撰写***等待时仍然不是一件事),那么您可以使用 async/await 来使您的代码更具可读性:

const response = await fetch(url);
const content = await response.json();
console.log(content);

【讨论】:

啊,棘手的部分正是我自己弄得有点太棘手了 :) 所以它要么是链接,要么是嵌套 response.json().then(r => console.log(r)) @Džuris 正是。我不鼓励嵌套,因为它违背了菊花链承诺的目的(这更漂亮/更具可读性)。 感谢上述澄清,@Terry。我对1点有点困惑。第一个 Promise 中的响应是否包含来自“开始”的 HTTP 响应正文。我想知道为什么它的设计方式是你需要获取另一个 Promise 才能获取身体。它实际上在做什么,在引擎盖下?发送 :)【参考方案2】:

fetch 返回的第一个承诺在某些情况下可能很有用。如果你想避免样板,你可以简单地创建自己的函数:

function fetch_json(url, opts) 
    return fetch(url, opts)
        .then(resp => resp.json());


fetch_json(your_url)
    .then(json => console.log(json));

【讨论】:

这是我推荐的。它避免了一遍又一遍地重复相同的代码。当您只需要 JSON 时,您可以使用这一个实用功能。【参考方案3】:

这些天我使用的是相同的 async/await 语法,但在我看来不像样板。

const response = await fetch(url)
const data = await response.json()

console.log(data)

【讨论】:

以上是关于我能以某种方式在第一个“then”中获得 fetch 响应吗?的主要内容,如果未能解决你的问题,请参考以下文章

libgdx- pixmap:我能以某种方式改变线条的宽度吗?

NewbieQuestion:我能以某种方式从 DAO 向 Spring+Hibernate 传递参数吗?

删除 SQL 中的重复行

2 服务沟通

Visual Studio Express中缺少文件,无法打开项目;如果我重新创建项目,我还能以某种方式与Github同步吗?

找出谁在调用方法