18

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

4

3 回答 3

13

一种方法是通过给它们随机 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,你就没有这种奢侈,因为 Promise 缺乏这种行为。

于 2016-05-26T15:08:36.763 回答
4

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

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

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

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

编写一个中间件,每当一个 api 请求完成时,它都会存储相关的操作类型。与它一起,它存储一个标志,表明是否放弃此操作。如果再次触发类似类型的操作,请将此标志设为 true,表示丢弃此操作。由于此 api 请求的丢弃标志已设置为 true,因此当上一个操作的 api 响应出现时,发送 null 作为来自中间件的响应。

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

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

于 2018-05-15T09:36:24.463 回答
4

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

动作创建者

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

你的组件

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

  somefnct() {
    this.previousPromise.abort();
  }
于 2017-03-14T14:31:03.330 回答