【问题标题】:Can I somehow get the fetch response in the first `then`?我能以某种方式在第一个“then”中获得 fetch 响应吗?
【发布时间】: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 语法是唯一的方法。

【问题讨论】:

    标签: javascript es6-promise fetch-api


    【解决方案1】:

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

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

    流程如下所示:

    1. 发出fetch() 请求,它返回Response 类型的Promise
    2. 当你尝试解析Response的内容时,它会返回第二个Promise,它的类型取决于你使用的方法(例如.json()返回一个对象,.text()返回字符串,.blob()返回Blob) .
    3. 解决第二个 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)
    

    【讨论】:

      猜你喜欢
      • 2021-05-22
      • 2023-02-14
      • 2023-03-20
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      相关资源
      最近更新 更多