繁体   English   中英

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

[英]Cancelling previous async action using redux-thunk

我正在使用redux-thunk中间件构建一个React / Redux应用程序来创建和处理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,你可以让你的动作创建者返回promise,它将由dispatch函数返回,然后它就可以中止它。 这是一个例子:

行动创造者

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

你的组件

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

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

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

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

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

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

编写中间件,每当完成api请求时都会存储相关的操作类型。 除此之外,它还存储一个标志,指出是否放弃此操作。 如果再次触发类似类型的操作,请将此标志设为true,表示放弃此操作。 当api响应来自之前的操作,因为此api请求的discard标志已设置为true,因此从中间件发送null作为响应。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM