4 способа побороть Race Condition
HTML-код
- Опубликовано: 29 июн 2024
- В каждом проекте встречается проблема Race Condition. И из моего опыта многие игнорируют ее, пока уже тестировщик явно не укажет на баг. И сегодня мы рассмотрим 4 способа как всего в пару строк побороть Race Condition
Разверните мощную облачную базу данных за пару кликов в Selectel: slc.tl/fssx2
документация useEffect - react.dev/reference/react/use...
Первая часть видео: • Нет useEffect, нет баг...
Вторая часть видео: • Как я работаю с deboun...
ТГ канал - t.me/it_sin9k
Поддержать Айти Синяка можно здесь:
RUclips: / @it-sin9k
boosty: boosty.to/sin9k
Patreon: / itsin9k
00:00 Анонс темы
00:32 Аутсорсинг БД - Selectel
01:56 Что такое Race Condition?
02:45 useEffect + AbortController
03:39 useEffect + ignore
04:25 ref + AbortController
05:08 ref + requestIndex
05:50 А вы испольузете AbortController?
Подписаться на канал: / @it-sin9k
Twitter: / it_sin9k
Где-то была статья от автора react query, где он описывает все возможные сложности, которые возникают при самом простом сетевом запросе и сохранении результата в стейт. Если коротко, то race condition там далеко не единственная возможная проблема, и в результате нужна целая стена текста для обработки всех ситуаций. Почему он и сделал эту библиотеку - чтобы делать все это одним хуком вместо стены текста.
Звучит как крутая статья) почитал бы)
Сбросьте ссылку на статью, пожалуйста :)
Common Patterns and Nuances Using React Query
фактанул
Спасибо! Очень полезное видео!
А еще есть старое доброе поле ввода без дурацких отвлекающих подсказок, и с отдельной кнопкой поиска (и по enter разумеется). Никаких гонок, никакого дрочения сервера ненужными запросами) Очень раздражает, когда поле ввода пытается за меня решить, что же мне нужно) Такое ощущение, что когда увидели ajax впервые, обрадовались, что не надо отправлять форму и перезагружать страницу, и присобачили его везде где надо и не надо) Это ни в коем случае не наезд на видео, ибо видео как обычно полезное и нужное. Просто высказал мнение по поводу автоподсказок в инпуте - мне они не нравятся со всех точек зрения - пользователя, фронтенд- и бэкенд-разработчика)
Саш привет! Спасибо за видео. В react-query, queryFn пробрасывает параметр signal. Так что если у вас уже есть клиентская абстракция над rest типа: post(url, data) => (signal) => {...} то все запросы будут отменяться, это очень удобно для юзеров с медленным интернетом. По умолчанию все запросы доводятся до конца, что иногда слишком, если учитывать что юзер на ту страничку не вернётся и кликнул её случайно. И кстати, наверное new AbortController скорее должен быть один, при той же настройки axios instance. его же можно потом абортить из любой точки.
Про useQuery планирую записать отдельное видео)
Главное не отмеить таким образом получение скидки по промокоду , или любое другое действие которое должно 100% прийти обратно клиенту(если конечно стейт не хранится на сервере , тогда купон не пропадет) 🤗
А кто ведет логи отмены запросов кстати?
@@alexs7931 Клиент, конечно) Так отмена запросов в основном когда происходит внезапный unmount (быстро переключая табы, например). Если запросить промокод и уйти с экрана, то спрашивается нужен ли он на новом?)
Спасибо за видео. Я как раз в предыдущих спрашивал про этот случай. Но мне почему-то кажется, что все является неким костылем и нужно добавлять дополнительный код чтобы логика работала так как надо. К тому же если я хочу просто свою асинхронную операцию как то отменить, а не сетевую, abort controller мне не подойдет. Во общем нужно создавать какой-то свой кастомный враппер, чтобы это хотя бы чистенько выглядело
т.е. вы хотите отменить асинхронные функции? даже не связанные с запросом? а можно пример?
Используем логическую переменную типа "нужно или нет" менять стейт
ну явно лучше если аборт контроллер используется 1-2 раза, а не 100 потому что это копипаста говнокод, и race condition надо решать не на уровне компонента, а выше
У это проблемы две половины. Одна - непредсказуемый порядок получения ответов от сервера. В видео разбираются подходы для решения этой части. Вторая - непредсказуемый порядок получения запросов сервером. Клиент, отправляя сначала запрос А, а потом Б, не может быть уверен, что сервер получит их именно в этом порядке. Например, мы делаем редактор документов аля гугл док. Сохраняем текущую версию документа на сервер раз в секунду. Теперь, что будет если запрос отправленный последним, придёт на сервер предпоследним? На сервере окажется не та версия документа.
У нас на проекте есть удобная обёртка для запросов с аборт контроллером, которая используется почти везде. А ещё есть конструкция для проверки имеется ли файл на сервере (суть в том что существует только запрос, который скачивает файл, но нам не нужен сам файл, он очень большой, потому мы просто абортим запрос когда файл начинает скачиваться)
а почему сервер не может просто сказать, есть файл или нет?)
@@it-sin9kНет возможности что-то сделать с сервером), а у него настройка всегда на download или что-то тип того. На тот момент я ничего не нашел, чтобы не менять запрос на сервере
На моем проекте нашлось 4 места где создается инстанс аборт контроллера
Первый и самый очевидный в твоем примере функция дебонс. Как мне кажется) ну и честно к вопросу подходя
Я не знаю какого качества надо писать код чтобы пришлось юзать аборт контроллеры и тд
Проблема очевидна всегда. Либо бекенд и медленный серв. Фронт не должен закрывать костылями с абортами бекенд плохоработающий
Второй криво написан сам фронт - проблема та же. Не надо делать костыли. Нужно делать простой и понятный код.
Ошибаешься. Как раз фронтенд должен думать, что делать, если бек долго отвечает. Перекинуть ответственность тут не получится, типичный реактовец
@@ihateidiots9484 не должен если у бека руки из попы проблемы его
Я могу это делать и заглушки в любом случае будут но это не фронта зона ответственности.
Перевелу стрелки. Очередной говнокодер сеньор с 10 летним опытом? 🙂
а как вы ожидаете должно работь приложение, если нужно отправить 2 подряд запроса с очень маленькой разницей?
@@it-sin9k можно пример, Саш (:
Се то не пойму ) есть может редкий кейс где пригодится но он редкий)
сеньор небось?)
Шёл 24 год, а всё базовые вещи разбирают
а что хотелось бы обсудить в 24 году?)
какие есть решения добавить таймауты для фетч? АбортКонтроллер ? это в офисе интернет хороший, а при использовании мобилок приложение может надолго зависнуть и только перезагрузка страницы решает проблему?
я так понял, вы хотите поставить кастомное время на выполнения fetch? насколько я вижу примеры в гугле, в основном только через AbortController + setTimeout
@@it-sin9k верно. Интересно и серверное и клиент решение
Будет обзор React 19? Лень читать )
Обязательно) обзор + поковыряем корнер кейсы)
null абортконтроллеров
ахаха)
Ха! Целых 6 раз аборт контроллер вызывается! Из нескольких сотен запросов...
это на 4 больше чем у нас))
Вот и сюда пришла реклама занявшая 1/4 всего видео :(
У нас не было рекламы примерно пол года) поэтому надеюсь терпимость и даже осмелюсь попросить поддержку перейти разок по ссылке)
@@it-sin9kдаже на комментарии с недовольством рекламы включили рекламу)
надо же как то из лимонов делать лимонад))
Люди хотят кушать и зарабатывать, сохраняя возможность транслировать бесплатный контент. Это не казино, ставки и уже спасибо, это вполне полезная реклама для аудитории. К тому же, видео размечено по тайм-кодам и можно легко пропустить, если это не интересно
@@it-sin9k у меня хоть и стоит пропуск рекламы но сходил по ссылке, спасибо за труд
Дело в том что бек тоже должен обрабатывать аборт, у нас к примеру не умеет и смысла мне использовать нету
хмм, а что сервер должен делать? вроде это же на клиенте просто рветься соединение.
@@it-sin9k да но сервер его уже принял, отправил запрос в базу и тут я сказал ему что данные этого запроса меня уже не интересуют, со своей стороны понятно я сэкономлю трафик, а со стороны бека, разве не должно быть такой же аборт для остановки запроса в БД
@@it-sin9k на клиенте. это чувак бредит чутка
@@it-sin9k PHP, например, по дефолту прибивает скрипт сразу же, как рвётся соединение. В общем случае, сервер может это обрабатывать (при желании) с помощью бэкэндного аналога AbortController.
@@it-sin9k да, запрос на сервере вызовет запрос в бд, то что мы его остановим не обрывает запрос сервера. Ну вызвали, для update нет смысла абортить, а в случае использования кеширования то и на гет смысла нет
Оффтоп: *Что случилось с Yarn?*
он уже не тот
@@Dmitriy-bq2xh я понял, что "не тот"...
Вариант с игнорированием череват исчерпанием ширины канала или превышением количества открытых сокетов (если используется HTTP/1).
Обычно для решения подобных задач есть специализированные решения на подобии RxJS (особенно актуально для Angular). Там это можно сделать просто оператором switchMap.
Жаль что React разработчики боятся использовать RxJS или ленятся использовать хотя бы AbortController.
Использовать целую библиотеку для одной функции - такое себе. AbortController самое то
@@grenadier4702 разумеется если у вас маленькое приложение. Но в каком-нибудь здоровенном энтерпрайз приложении использование специализированного решения позволяет сократить время разработки и поднять качество кода.
К тому же нет ничего плохого в том чтобы использовать аж целую библиотеку для одного случая. Все равно основная часть библиотеки будет отброшена. Также это исключает необходимость переписывания на специализированное решение впоследствии при разрастании приложения.
@@dimonsoftinfo достаточно либо найти маленькую библиотеку под конкретное решение, либо самому один раз написать, протестировать и использовать во всех своих проектах
Вы несколько раз повторяете "специализированное решение" говоря про RxJS. Специализированное для чего?
RxJS - это про потоки событий. Их можно мапить, фильтровать, мёрджить и ещё стопицот "операторов". На фронте такая концепция как собаке пятая нога. Чаще всего проще (и лучше) написать тупой обработчик клика (одного), а не складывать клики в поток обвешанный "операторами". Штука крутая, никто не спорит, но либо в других задачах, либо как разминка для мозгов, либо, на худой конец, как повод выпендриться перед посонами в подвёрнутых штанишках. На фронте в продакшене от неё только повышенная сложность и около нуля пользы.
React настолько уныл, что даже в документации к нему рекомендуют бред с булевой переменной ignore