【问题标题】:Cancelling previous async action using redux-thunk使用 redux-thunk 取消之前的异步操作
【发布时间】:2016-09-19 13:14:27
【问题描述】:

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

【问题讨论】:

    标签: reactjs redux redux-thunk


    【解决方案1】:

    一种方法是通过为这些请求提供随机 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

    在reducer中有这样的东西:

    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 缺乏这种行为。

    【讨论】:

      【解决方案2】:

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

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

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

      redux 中的每个 api 请求都关联一个 action,每个 action 都有一个 type 和一个 payload。

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

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

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

      【讨论】:

        【解决方案3】:

        如果你使用jquery ajax,你可以让你的action creator返回promise,它会被dispatch函数返回,然后就可以中止它。这是一个例子:

        动作创建者

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

        你的组件

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

        【讨论】:

        • 你不应该再使用jQuery了。
        猜你喜欢
        • 2018-01-31
        • 1970-01-01
        • 2017-03-03
        • 2021-10-04
        • 2020-01-17
        • 2020-06-05
        • 2019-12-17
        • 2016-12-20
        • 2020-10-28
        相关资源
        最近更新 更多