簡體   English   中英

提取API-然后在兩者中獲取json主體,並捕獲塊以獲取單獨的狀態代碼

[英]Fetch api - getting json body in both then and catch blocks for separate status codes

我正在使用fetch api來獲取可能返回的URL:

響應:狀態= 200,json正文= {'用戶':'abc','id':1}

要么

響應:狀態= 400,json正文= {'原因':'某種原因'}

要么

響應:狀態= 400,json正文= {'原因':'其他原因'}

我想從代碼的各個部分中創建一個單獨的功能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()承諾,並從鏈接到response.json() .then()內部返回包含datastatus對象。

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

這是略有不同的方法:使用單行代碼,使用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))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM