首页 文章

获取api - 在两者中获取json body并捕获块以获取单独的状态代码

提问于
浏览
1

我使用fetch api来获取可能返回的URL:

响应:status = 200,json body = {'user':'abc','id':1}

要么

回复:状态= 400,json body = {'reason':'某种原因'}

要么

回复:状态= 400,json body = {'reason':'其他原因'}

我想创建一个单独的函数 request() ,我在代码的各个部分使用如下:

request('http://api.example.com/').then(
        // status 200 comes here
        data => // do something with data.id, data.user
    ).catch(
        // status 400, 500 comes here
        error =>  // here error.reason will give me further info, i also want to know whether status was 400 or 500 etc
    )

我无法进行200到400,500之间的分割(我试过抛出一个错误) . 当我抛出错误时,我发现很难仍然提取JSON主体(用于error.reason) .

我目前的代码如下:

import 'whatwg-fetch';

/**
 * Requests a URL, returning a promise
 */
export default function request(url, options={}) {

    console.log('sending api request, url = ' + url)

    return fetch(url, options)
        .then(checkStatus)
        .then(parseJSON)
        .then((data) => ({data}))
        .catch((err) => ({err}));
}


function checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
        return response;
    }

    const error = new Error(response.statusText);
    error.response = response;
    throw error;
}



function parseJSON(response) {
    return response.json();   // json() is a promise itself
}

我试图通过执行如下操作来解决此问题,通过反转 .then() 调用的顺序,但不起作用

export default function request(url, options) {
    return fetch(url, options)
        .then(parseJSON)        // note that now first calling parseJSON to get not just JSON but also status. 
        .then(checkStatus)      // i.e. Inverted order of the two functions from before

        .then((data) => ({data}))
        .catch((err) => ({err}));
}

function checkStatus({data, status}) {

    if (status >= 200 && status < 300) {
        return data;
    }
    else {
        // const error = new Error(response.statusText);
        const error = new Error("Something went wrong");
        // error.response = response;
        error.data = data;

        throw error;
    }

}

function parseJSON(response) {
    let jsonBody

    response.json().then(json => {
        jsonBody = json                 // this does not help, i thought it will make jsonBody fill up, but seems its in a diff thread
    })              

    return {
        data: jsonBody,
        status: response.status     // my aim is to send a whole dict with status and data to send it to checkStatus, but this does not work
    }
}

2 回答

  • 6

    response.json() 返回异步结果 . 您没有将 parseJSON 处的对象从 .then() 链接到 response.json() . 要纠正该问题,您可以在 parseJSON 调用时返回 response.json() promise并返回包含 datastatus 的对象,从 .then() 链接到 response.json()

    function parseJSON(response) {
        return response.json().then(json => {
              return {
                       data: json,
                       status: response.status  
                     }
        })         
    }
    
  • 0

    这里有一个稍微不同的方法:使用单行程我用ok,status和json-as-object(不是promise)创建一个类似响应的promise,然后我决定如何处理这个对象 . 一般来说,如果response.ok为false,我会拒绝响应,否则我只使用json-data解析 . 网络错误/ json-parse-errors像往常一样被拒绝 .

    fetch(url, options)
        .then(r => r.json().then(json => ({ok: r.ok, status: r.status, json})))
        .then( r => r.ok ? r.json: Promise.reject(r))
    

相关问题