如何在使用同构获取的异常处理承诺后解析 json

how to parse json after exception handling promise with isomorphic-fetch

在使用 React、Redux、isomorphic-fetch、ES6 Babel 实现登录功能的过程中。

问题

我不知道如何在 checkstatus 承诺之后正确组合承诺,以便从我的服务器获取已解析的 JSON 数据。
我在这里做错了什么?

另外,我需要用其他更方便的包替换 isomorphic-fetch 包吗?
欢迎对其他包装提出任何建议!

loginAction.js

import * as API from '../middleware/api';
import * as ActionTypes from '../actionTypes/authActionTypes';
import 'isomorphic-fetch';

function encodeCredentials(id, pwd) {
  return btoa(`${id}{GS}${pwd}`);
}

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    response;
  } else {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

function parseJSON(response) {
  return response.json();
}

export function loginFailure(error) {
  return { error, type: ActionTypes.LOGIN_FAILURE };
}

export function loginSuccess(response) {
  return dispatch => {
    dispatch({ response, type: ActionTypes.LOGIN_SUCCESS });
  };
}

export function loginRequest(id, pwd) {
  return {
    type: ActionTypes.LOGIN_REQUEST,
    command: 'login',
    lang: 'en',
    str: encodeCredentials(id, pwd),
    ip: '',
    device_id: '',
    install_ver: '',
  };
}


export function login(id, pwd) {
  const credentials = loginRequest(id, pwd);

  return dispatch => {
    fetch(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, {
      method: 'post',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(credentials),
    })
    .then(checkStatus)
    .then(parseJSON)
    .then(data => {
      console.log(`parsed data ${data}`);
      dispatch(loginSuccess(data));
    })
    .catch(error => {
      console.log(`request failed ${error}`);
    });
  };

}

你做对了,你只是在checkstatus中忘记了return;您应该 return response 以便链中的下一个承诺可以使用它。

另外,checkstatus好像是同步操作,所以没必要用.then串起来(不过,喜欢这样也没关系),你可以这样写:

fetch(...)
.then(response=>{
   checkStatus(response)
   return response.json()
})
.then(data=>{
   dispatch(loginSuccess(data))
})
.catch(...)

我认为暂时没有理由摆脱 isomorphic-fetch - 它似乎已经完成了它的工作。

通常在我的项目中,我有一个辅助函数 fetchJSON 执行所有实用程序逻辑,例如 JSON 解析和状态检查。

这里是:

import fetch from 'isomorphic-fetch';

function checkStatus(response) {
  if(response.ok) {
    return response;
  } else {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

function parseJSON(response) {
  return response.json();
}

export default function enhancedFetch(url, options) {
  options.headers = Object.assign({
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  }, options.headers);
  if(typeof options.body !== 'string') {
    options.body = JSON.stringify(options.body);
  }
  return fetch(url, options)
    .then(checkStatus)
    .then(parseJSON);
}

然后你就可以在动作中使用它了:

import fetchJSON from '../utils/fetchJSON'; // this is the enhanced method from utilities

export function login(id, pwd) {
    const credentials = loginRequest(id, pwd);

    return dispatch => {
       fetchJSON(`${API.ROOT_PATH}${API.END_POINT.LOGIN}`, {
           method: 'post',
           body: credentials
       }).then(data => {
           console.log(`parsed data ${data}`);
           dispatch(loginSuccess(data));
       }).catch(error => {
           console.log(`request failed ${error}`);
       });
   };
}

它可以帮助您保持动作代码与某些样板代码的区别。在具有大量类似 fetch 调用的大型项目中,这确实是一件 must-have 事情。