获取response.json()和response.status

问题描述 投票:0回答:6

这是使用 body.json() 并获取状态代码的唯一方法吗?

let status;

return fetch(url)
    .then((response => {
         status = response.status;
         return response.json()
     })
    .then(response => {
        return {
            response: response,
            status: status
        }
    });

这不起作用,因为它在响应字段中返回一个承诺:

.then((response)=> {return {response: response.json(), status: response.status}})
javascript promise fetch-api
6个回答
125
投票

您的状态在第二个

then
中不可见。您可以在单个
then
中获取这两个属性。

json()
返回一个新的 Promise,因此您需要在该函数结果的
then
内创建对象。如果您从函数返回 Promise,它将被履行并返回履行的结果 - 在我们的例子中是对象。

fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(r =>  r.json().then(data => ({status: r.status, body: data})))
.then(obj => console.log(obj));


31
投票

.json
方法返回一个承诺,而不是解析的值本身。如果您想在同一个回调中访问响应和解析值,则需要使用如下嵌套函数:

fetch(url).then(response => {
    response.json().then(parsedValue => {
        // code that can access both here
    })
});

或者,您可以在异步函数中使用

await
来消除对回调的需要。

const response = await fetch(url);
const parsedValue = await response.json();

// code that can access both here

当然,您需要通过对 Promise 的

.catch(...)
调用或在
try...catch
函数中使用
async
块来检查错误。您可以创建一个处理 JSON 和错误情况的函数,然后将其重用于所有提取。例如,这样的事情:

function handle(response) {
    if (response.ok) {
        return response.json().then(parsedValue => {
            // the status was ok and the body could be parsed
            return { response, parsedValue };
        }).catch(err => {
            // the status was ok but the body was empty or not JSON
            return { response };
        });

    } else {
        return response.json().catch(err => {
            // the status was not ok and the body was not JSON
            throw new Error(response.statusText);
        }).then(parsedValue => {
            // the status was not ok and the body was JSON
            throw new Error(parsedValue.error); // assuming our API returns an object with an error property
        });
    }
}

我不认为这是最好的设计模式,但希望这能澄清 fetch API 的工作原理。请注意,如果某些因素阻止请求首先发送,则对

fetch
的调用本身可能会引发错误。

PS:我避免命名任何变量或属性

json
,因为这是文本格式的名称。一旦被解析,它就不再是 JSON。您可能想使用比
parsedValue
更有意义的名称。


16
投票

使用两个“then”对我来说似乎没有必要。

async/await 可以很轻松地完成工作。

    fetch('http://test.com/getData')
      .then( async (response) => {

        // get json response here
        let data = await response.json();
        
        if(data.status === 200){
         // Process data here
        }else{
         // Rest of status codes (400,500,303), can be handled here appropriately
        }

      })
      .catch((err) => {
          console.log(err);
      })

0
投票

你尝试过这个吗?

return fetch(url)
    .then((r)=> {return {response: r.json(), status: r.status}})

0
投票

我认为最简洁的方法是使用您需要的部分创建 Promise.all() 。

.then(response => Promise.all([Promise.resolve(response.ok), response.text()]))

可以写得更短为

.then(response => Promise.all([response.ok, response.text()]))

promise 返回一个包含所有结果的数组

.then(data => ({ status: data[0], response: data[1] }))


0
投票

引入

async
await
可以轻松地在一处处理来自依赖 Promise 的数据。

由于不涉及回调函数的使用,所以变量都存在于同一个作用域中。

const myFunction = async (url) => {
    const response = await fetch(url);
    const status = response.status;
    const data = await response.json();
    return { data, status };
};
© www.soinside.com 2019 - 2024. All rights reserved.