Задать вопрос

Библиотека асинхронных запросов для react?

Если ajax запрос данных с сервера может быть длительным (2 и более секунд), в современных фреймворках типа react без проблем можно отображать progressbar, значок загрузки и т.п. Но в это время пользователь имеет право работать с приложением дальше, нажимать различные кнопки, т.е. запускать другие процессы загрузки данных и т.п. Так вот вопрос - существует ли на данный момент библиотека, которая способна разрулить такой хаос в действиях пользователя?
Пример некорректных возможных обработок:
1) Клиент выбрал фильтры в форме поиска, нажал кнопку, данные грузятся... далее юзер выбрал другие параметры фильтров, снова нажал кнопку - в результате второй запрос теоретически может отработать быстрее первого, затем придут данные от первого запроса, в результате - параметры заданных юзером фильтров будут от второго запроса, а отображаемый результат - от первого.
2) Повторная отсылка данных формы - тут конечно есть стандартный метод блокирования кнопки от нажатия, но желательно бы это перенести на функциональность быблиотеки.

Вот примерное тз для такой библиотеки:
Типы процессов:
1) Получение доп данных (например полный текст статьи в блоге)
- Если target компонент скрывается (переходим на другую вкладку, закрыли компонент, и т.п.) - то отменяем процесс.
- Если повторный запрос тех же самых данных - игнорируем такой запрос.
- Отменить загрузку можем и по нажатию кнопки.
2) Получение дынных формы с заданными фильтрами на входе (поиск по параметрам например)
- Во время загрузки фильтры показываем как их выбрал юзер.
- Если target компонент скрывается, то отменяем процесс.
- Если задали другие фильтры на входе, то отменяем прежний процесс и создаем новый.
- Если отменили загрузку, то возвращаем фильтры в исходное состояние.

+ данные могут поступать по websocket

В общем случае это получается некий конечный автомат с правилами на любой штатный/внештатный случай. Есть ли сейчас что-то такое готовое?
  • Вопрос задан
  • 1369 просмотров
Подписаться 11 Оценить 1 комментарий
Ответ пользователя Никита Гущин К ответам на вопрос (4)
Да, такая библиотека есть. Проблема в том, что в JS нативные промисы (Promise) нельзя отменить (not cancelable)... но при этом - у нас есть генераторы, которые вполне себе позволяют имитировать отмену выполнения какой-либо функции, скажем, в середине.

Для того, чтобы все заработало - вам нужно использовать связку из любой понравившейся библиотеки для непосредственно запросов (я предпочитаю isomorphic-fetch), затем взять redux и middleware для него (редакса) - redux-saga.

Если вы не знакомы с экосистемой редакса или первый раз слышите про redux-saga - прочтите документацию, посмотрите уроки. Если вкратце - библиотека построена на генераторах. Функция-генератор возвращает итератор и ее выполнение прекращается каждый раз, когда мы возвращаем итератору новое значение (yield)

Ниже продемонстрирую как это примерно работает:

function* myCancelableAction(someData) {
  // вернет итератору промис и приостановит работу функции до следующего вызова next
  // в нашем случае - функция продолжит выполнение, когда придет ответ сервера
  const response = yield doAjaxRequest(someData) 
  yield dispatchSuccessAction(response)
}

const action = myCancelableAction();
const promise = action.next().value // fetch promise

promise.then(response => {
  // если новых запросов не поступило
  if(!newRequestIsComing) {
    // мы можем передать значение в нашу функцию (через next)
    console.log(action.next(response).value); // dispatched action
  }
})


Таким образом, после того, как функция вернула значение первый раз, применительно к теме поста это будет "сделай AJAX-запрос", мы можем не выполнять ее дальше (если захотим). Отменить ajax запрос в этом случае не получится, но мы можем просто не учитывать его результаты (не диспатчить success-экшен, например).

UPD1 обновил пример кода
Ответ написан
Комментировать