使用 redux-thunk 取消之前的异步操作

Cancelling previous async action using redux-thunk

我正在构建一个 React/Redux 应用程序,使用 redux-thunk 中间件来创建和处理 Ajax 请求。我有一个经常被触发的特定 thunk,我想在触发新请求之前取消任何先前启动的 Ajax 请求。这可能吗?

一种方法是通过给这些请求随机 ID 并在处理结果之前检查其状态来将这些请求标记为已取消。

这样做的方法是在您的第一次调度中(在 thunk 内)为这个调用分配随机 ID,并在处理结果之前在 reducer 中检查它。

const actionId = Math.random();
dispatch({type: AJAX_LOAD_CONST, id:actionId })

当你想取消所有请求时使用

dispatch({type:HANDLE_AJAX_RESPONSE, id:actionId, results: json })

当您想处理结果时,请不要忘记发送您的 ID

在减速器中有这样的东西:

function reducer(state = initialState, action) {
  switch (action.type) {
    case actions.AJAX_LOAD_CONST:
      return Object.assign({}, state, { ajax: state.ajax.concat(action.id) });
    case actions.CANCEL_ALL_AJAX:
      return Object.assign({}, state, { ajax: [] });
    case actions.HANDLE_AJAX_RESPONSE:
      if (state.ajax.includes(action.id) {
        //return state reduced with action.results here
      }
      return state;
  }
}

如果您使用 XMLHttpRequest 或其包装器之一(JQuery?),您还可以自己存储请求并调用 request.abort()。如果你使用新的 fetch api 你就没有这种奢侈,因为 promises 缺乏这种行为。

如果您正在使用 jquery ajax,您可以让您的动作创建者 return 承诺,它将由调度函数 return 编辑,然后可以中止它。这是一个例子:

动作创作者

function doSomething() {
  return (dispatch) => {
    return $.ajax(...).done(...).fail(...);
  }
}

你的组件

  componentDidMount(){
    this.previousPromise = this.props.dispatch(doSomething());
  }

  somefnct() {
    this.previousPromise.abort();
  }

我最近遇到了同样的问题,我不得不取消挂起或陈旧的异步 redux 操作。我通过创建一个取消 redux 操作中间件来解决它。

在redux中我们有中间件的概念。因此,当您发送请求时,它将通过中间件列表。一旦 api 响应,它的响应将在到达 redux 存储之前通过许多中间件,最终到达您的 UI.

现在假设我们已经写了一个取消中间件。 api 请求在发起时将通过此中间件,而 api 响应在 api 响应时也将通过此中间件。

redux 中的每个 api 请求都与一个动作相关联,每个动作都有一个类型和负载。

编写一个中间件,每当 api 请求完成时,它都会存储关联的操作类型。与它一起,它存储一个标志,该标志表明是否放弃此操作。如果类似类型的动作再次被触发,使这个标志为真,表示放弃这个动作。由于此 api 请求的丢弃标志已设置为真,因此当针对前一个操作的 api 响应到来时,发送 null 作为来自中间件的响应。

查看此博客以了解有关此方法的详细信息。

https://tech.treebo.com/redux-middlewares-an-approach-to-cancel-redux-actions-7e08b51b83ce