如何取消以前的axios请求?

时间:2020-03-11 16:07:27

标签: reactjs react-redux axios

创建新请求时,如何在React / Redux中取消以前的axios请求?

这是我在Google上找到的选项之一,但不起作用。

action.js

class FilmsActions {
  getFilmList(searchParams = undefined, cancelToken = null) {
    return async dispatch => {
      dispatch(filmsFetchRequest());
      try {
        const res = await api.get(`/films/${searchParams && searchParams}`, {
          cancelToken,
        });
        return setTimeout(() => dispatch(filmsFetchSuccess(res.data)), 1000);
      } catch (err) {
        return setTimeout(() => dispatch(filmsFetchError(err)), 1000);
      }
    }
  }
}

export const filmsActions = new FilmsActions();

app.js

import axios from 'axios';

class BrowseFilms extends Component {
  ...

  componentDidUpdate(prevProps) {    
    const {
      getFilmList,
      location,
      loading,
    } = this.props;

    if (prevProps.location.search !== location.search) {    
      if (loading) {
        this.source.cancel();
      }

      this.source = axios.CancelToken.source();

      getFilmList(location.search, this.source.token);
    }
  }

  ...
}

const mapStateToProps = state => ({
  data: state.films.data,
  loading: state.films.loading,
});

const mapDispatchToProps = dispatch => ({
  getFilmList: (searchParams, cancelToken) => dispatch(filmsActions.getFilmList(searchParams, cancelToken)),
});

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(BrowseFilms));

在这种情况下,它不会取消请求。如果交换(在componentDidUpdate中)if (loading)this.source,它将取消请求,但取消下一个请求,而不是上一个请求。

1 个答案:

答案 0 :(得分:0)

事实证明,问题出在服务器返回响应太快而无法取消的情况下。

为避免这种情况,您需要更改action.js。

action.js

const delay = ms => {
  return new Promise(resolve => setTimeout(resolve, ms));
}

class FilmsActions {
  getList(searchParams = undefined, cancelToken = null) {
    return async dispatch => {
      dispatch(filmsFetchRequest());
      try {
        await delay(1000);
        const res = await api.get(`/films/${searchParams && searchParams}`, {
          cancelToken,
        });
        return dispatch(filmsFetchSuccess(res.data));
      } catch (err) {
        if (!axios.isCancel(err)) {
          return dispatch(filmsFetchError(err));
        }
      }
    }
  }
}

export const filmsActions = new FilmsActions();