Представьте: вы пишите приложение с bloc, и у вас есть кнопка для загрузки данных. Пользователь может нажимать на эту кнопку бесконечное количество раз. К чему это приведет? Скорее всего — к множественным вызовам методов бэка и ухудшению работы UI.
Или, например, у меня была похожая ситуация с чипами, которые можно было выбирать. Запрос на бэк отправлялся при каждом выборе, не только при окончательном.
Как же это исправить? Можно подключить bloc_concurrency. Он позволяет управлять порядком и способом обработки событий в Bloc. Пакет идет вместе с bloc и предоставляет набор функций (EventTransformer’ов) для контроля того, как Bloc обрабатывает события.
По умолчанию в Bloc события обрабатываются строго одно за другим (то есть, sequential()).
Но мы можем изменить это поведение с помощью разных трансформеров:
✔️ concurrent() — события обрабатываются одновременно. Например, если добавить два события одновременно, оба будут выполняться параллельно
✔️ sequence() — события обрабатываются строго по очереди. Если добавить два события одновременно, сначала будет обработано первое, затем второе и так далее
✔️ droppable() — любые новые события, добавленные во время обработки текущего, будут проигнорированы
✔️ restartable() — обрабатывается только последнее событие, предыдущие отменяются, если они еще не завершены
За счет чего это достигается?
Каждый Bloc в методе on<Event> принимает необязательный параметр transformer, который определяет, как события этого типа обрабатываются.
on<LoadMoreKeysEvent>(
_loadMoreKeys,
transformer: droppable(),
);
Также можно создать свой кастомный трансформер. Например, добавить небольшую задержку для поиска:
on<SetSearchQueryEvent>(
_setSearchQuery,
transformer: debounce(const Duration(milliseconds: 300)),
);
🔗Более подробно можете прочитать в документации к блоку.