获取api - get json主体在then和catch块为单独的状态码



我正在使用fetch api获取一个URL,可能返回:

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

Response: status = 400, json body = {'reason': 'some reason'}

Response: status = 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
    }
}

response.json()返回异步结果。您没有从链接到response.json().then()中返回parseJSON的对象。为了纠正这个问题,您可以在parseJSON调用时返回response.json()承诺,并从.then()中返回包含datastatus的对象,链接到response.json()

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

这里有一个稍微不同的方法:用一行代码创建一个类似响应的promise,包含ok、status和json-as-object(不是promise),然后决定如何处理这个对象。一般来说,我用回应来拒绝回应。ok为假,否则我只解析json-data。像往常一样拒绝网络错误/json-解析错误。

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))

相关内容

  • 没有找到相关文章

最新更新