5

我需要使用实时搜索 axios 请求取消上一个请求 - 我正在使用油门去抖动来发出请求,但是在删除现有单词并更新新值时我遇到了问题 - 在某些情况下会显示前一个单词的结果,我想我需要取消所有以前对相同 requestID 的请求,通读文章,但它们都不适用于我的用例。任何帮助都是我的代码。

减速器:

switch (action.type) {
case GETTING_DATA:
  return {
    ...state,
    results: action.payload,
  };
case SEARCH_DATA:
  return {
    ...state,
    Results: action.payload,
  };



export function getSearch(value) {
  return (dispatch) => {
    dispatch({
      type: GETTING_DATA,
    });
    const arg = {
      search: value,
    };
    apiGet('abc', arg).then(response => 
     getResults(dispatch, response));
  };
}
const getResults = (dispatch, response) => {
  dispatch({
    type: SEARCH_DATA,
    payload: response.data,
  });
};

服务:

export const apiGet = async (path = '', args = {}) => {
  const endpoint = "/aaa/aaa/aaa";
  try {
    return axios.get(endpoint, getConfig());
  } catch (e) {
  }
};
4

2 回答 2

5

尝试以下操作:

value作为有效负载传递给操作GETTING_DATA。这将在状态中存储最新请求的值。

然后,getResults将相同的值与响应数据一起发送到 reducer。在 reducer 内部,检查传入的值是否与通过getResults存储在 state 中的值相同GETTING_DATA

如果是这样,则此数据是响应最新请求而出现的,因此您希望将其存储在 state 中。否则,您可以忽略它。

换句话说:

行动:

switch (action.type) {
case GETTING_DATA:
  return {
    ...state,
    lastRequestTime: action.payload,
  };
case SEARCH_DATA:
  if (action.payload.lastRequestTime === state.lastRequestTime) {
    return {
      ...state,
      Results: action.payload.response,
    };
  } else {
    return state
  }

行动:

export function getSearch(value) {
  return (dispatch) => {
    const lastRequestTime = Date.now()
    dispatch({
      type: GETTING_DATA, 
      payload: lastRequestTime
    });
    const arg = {
      search: value,
    };
    apiGet('abc', arg).then(response => 
     getResults(dispatch, { response, lastRequestTime }));
  };
}
const getResults = (dispatch, response) => {
  dispatch({
    type: SEARCH_DATA,
    payload: response.data,
  });
};
于 2018-01-13T23:21:11.033 回答
0

您可以创建这样一个小助手包装器,并在需要取消先前请求的任何地方使用它:

// ../services.js

function createApi(baseURL) {
  const axiosInst = axios.create({
    baseURL,
  });
  // here you can set default headers:
  axiosInst.defaults.headers.common['Content-Type'] = 'application/json';
  // return the function with closure variable to use for canceling
  return (type = 'get') => {
    let call = null;
    return (url, data, config) => {
      if (call) {
        call.cancel('Only one request allowed!');
      }
      call = axios.CancelToken.source();
      const extConf = {
        cancelToken: call.token,
        ...config,
      };
      switch (type) {
        case 'request':
          return api[type](extConf);

        case 'get':
        case 'delete':
        case 'head':
          return api[type](url, extConf);

        default:
          return api[type](url, data, extConf);
      }
    };
  };
}

export const baseApi = createApi('http://localhost:5000/api/')

然后像这样在任何地方使用它:

import baseApi from '../servises.js';

const fetchItemsService = baseApi('post');

//...
componentDidMount() {
  fetchItemsService('/items').then(() => {});
}
//...

于 2019-03-06T13:56:26.570 回答