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

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


person Steven Musumeche    schedule 22.05.2016    source источник


Ответы (3)


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

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

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

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

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

Если вы хотите обработать результаты, не забудьте отправить идентификатор, который вы

а в редукторе есть что-то вроде этого:

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

person mrras    schedule 26.05.2016

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

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

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

Ваш компонент

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

  somefnct() {
    this.previousPromise.abort();
  }
person Mohamed Ramrami    schedule 14.03.2017
comment
Вам больше не следует использовать jQuery. - person refaelio; 28.04.2021

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

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

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

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

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

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

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

person Sumit Gupta    schedule 15.05.2018