javascript fetch response.json()和response.status

lnxxn5zx  于 2023-09-29  发布在  Java
关注(0)|答案(6)|浏览(83)

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

let status;

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

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

.then((response)=> {return {response: response.json(), status: response.status}})
kmbjn2e3

kmbjn2e31#

您的状态在第二个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));
plicqrtu

plicqrtu2#

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

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(...)调用,还是在async函数中使用try...catch块。您可以创建一个处理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更有意义的名称。

bwitn5fc

bwitn5fc3#

我觉得用两个“然后”似乎没必要。
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);
      })
f0brbegy

f0brbegy4#

asyncawait的引入使得在一个地方处理依赖promise的数据变得容易。
因为它不涉及回调函数的使用,所以变量都存在于同一个作用域中。

const myFunction = async (url) => {
    const response = await fetch(url);
    const status = response.status;
    const data = await response.json();
    return { data, status };
};
j2datikz

j2datikz5#

你试过这个吗

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

ogsagwnx6#

我认为最干净的方法是用你需要的部分创建一个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] }))

相关问题