我能以某种方式在第一个“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 传递参数吗?
Visual Studio Express中缺少文件,无法打开项目;如果我重新创建项目,我还能以某种方式与Github同步吗?