Отмена предыдущего асинхронного действия с помощью redux-thunk

Я создаю приложение React / Redux, используя промежуточное ПО redux-thunk для создания и обработки запросов Ajax. У меня есть определенный thunk, который запускается довольно часто, и я хотел бы отменить все ранее запущенные запросы Ajax перед запуском нового. Возможно ли это?

3 ответов


одним из подходов было бы отметить эти запросы как отмененные, предоставив им случайный идентификатор и проверив его статус перед обработкой результата.

способ сделать это-назначить случайный идентификатор для этого вызова в вашей первой отправке (внутри thunk) и проверить его в редукторе перед обработкой результата.

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

Если вы хотите отменить все запросы, используйте

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

когда вы хотите обрабатывать результаты не забудьте послать код что ты u

и в редукторе что-то вроде этого:

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?) вы также можете хранить сами запросы и запрос вызова.аборт.)( если вы используете новый api выборки, у вас нет этой роскоши, так как обещания не имеют этого поведения.


вы можете заставить своего создателя действия вернуть обещание, оно будет возвращено функцией отправки, тогда его можно будет прервать. Вот пример :

создатель действий

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

компонент

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

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

недавно я столкнулся с той же проблемой, в которой мне пришлось отменить отложенные или устаревшие асинхронные действия redux. Я решил это, создав промежуточное ПО cancel redux actions.

в redux у нас есть концепции промежуточных программ. Поэтому, когда вы отправляете запрос, он будет проходить через список промежуточных программ. Как только api ответит, его ответ пройдет через ряд промежуточных программ, прежде чем он достигнет Redux store и, в конечном итоге, вашего пользовательского интерфейса.

теперь предположим, что мы написали отмена промежуточного. Запрос api будет проходить через это промежуточное ПО, когда он инициируется, и ответ api также будет проходить через это промежуточное ПО, когда api ответит.

каждый запрос api в redux связан с действием, каждое действие имеет тип и полезную нагрузку.

напишите промежуточное ПО, которое при выполнении запроса api сохраняет связанный тип действия. Вместе с ним он хранит флаг, который указывает, следует ли отказаться от этого действия. Если действие похожие тип запускается снова, сделайте этот флаг true, который говорит отбросить это действие. Когда ответ api приходит для предыдущего действия, так как флаг сброса для этого запроса api установлен в true, отправьте null в качестве ответа от промежуточного ПО.

посмотрите на этот блог для получения подробной информации об этом подходе.

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