art5455
@art5455
Каюсь, задавал тупые вопросы, но господи... с каки

Как бороться с race condition при обращении к REST API во Vue?

Под race condition я подразумеваю такое состояние, когда пользователю отобразилось не то, что он хотел из-за отработки предыдущего запроса, наглядный пример:
https://sebastienlorber.com/handling-api-request-r... в разделе Adding network delays + failures
Возможное решение автора сохранять предыдущий запрос:
// A ref to store the last issued pending request
const lastPromise = useRef();
useEffect(() => {
  setData(null);
  // fire the api request
  const currentPromise = fetchStarwarsHeroData(id).then(
    async data => {
      await delayRandomly();
      throwRandomly();
      return data;
    },
  );
  // store the promise to the ref
  lastPromise.current = currentPromise;
  // handle the result with filtering
  currentPromise.then(
    result => {
      if (currentPromise === lastPromise.current) {
        setData(result);
      }
    },
    e => {
      if (currentPromise === lastPromise.current) {
        console.warn('fetch failure', e);
      }
    },
  );
}, [id]);

В react есть thunk, saga, а как правильнее сделать это во Vue?

Еще пример: гифка
  • Вопрос задан
  • 662 просмотра
Решения вопроса 3
Aetae
@Aetae Куратор тега Vue.js
Тлен
Просто не давть пользователю повторно тыкать там, где это вызовет повторный запрос, пока идёт загрузка текущего?

Но если хочется быть ленивым - можно просто обернуть запросы в leading debounce-promise.

Все эти thunk и saga - полная ересь, порождённая богомерзким redux.
Ответ написан
@VegasChickiChicki
Артур Галяев На самом деле то что у вас на скриншоте я решил у себя на проекте более практично - AbortController. Мы просто записываем текущий запрос в переменную, если пользователь сделал действие, которое создает еще запрос на тот же адрес, то мы отменяем предыдущий запрос и создаем новый, помещая его снова в переменную и так до тех пор пока пользователь не перестанет тыкать.

Так же можно комбинировать и добавить debounce + блокировку контента, ко посоветовали выше.
Ответ написан
Комментировать
@impruvd
Очевидно, гифка с кнопками - переупрощённый пример. Более-менее реальный для поднятой проблемы - построение динамической формы по её типу. Условно - есть дропдаун, в нём какие-то значения (тип формы), на изменение выбранного значения идёт fetch на сервер за набором полей, которые нужны для построения формы. Шапка формы вполне может билдиться из информации, полученной не от сервера в ответ на запрос полей, а из информации, известной заранее, при построении дропдауна с выбором типа формы, это нормально.
И в таком варианте, разумеется, надо блокировать контрол, ответственный за вызов бэкенда, а на контент по желанию вешать блюр, прелоадер, оверлей полупрозрачный, что угодно, чтобы пользователь понимал, что сейчас форма недоступна для взаимодействия, тыкать не надо (да и лишние запросы на бэкенд ходить не будут).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Как уже сказали блокировать кнопку.

Как пели давно "нажми на кнопку получишь результат" в вашем случае "нелязя нажать на кнопку"
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы