Для управления конкурентностью при общении с api.
mergeMap
… будет триггерить все запросы, конкурентно создавая гонку.
exhaustMap
… будет игнорировать все запросы, пока не завершится активный запросы.
concatMap
… будет создавать очередь запросов, где будет только один запрос активный, а остальные запросы будут ждать своей очереди.
switchMap
… отменит предыдущий запрос, гарантируя один активный запрос.
Наиболее популярные кейсы на практике для их использования
В кейсе формы создания какой-то сущности с последующим редиректом, exhaustMap, чтобы не отправлять тысячу запросов, если юзер будет кликать по кнопке, а она не дизейблится
В кейсе, когда у нас есть поиск и нам необходимо отправлять запрос на бэк, лучше подойдет switchMap, так как он будет отменять предыдущий запрос, если он не успел завершится и отправлять новый, с актуальными данными
Если мы патчим какую-то сущность, тогда в большинстве случаев лучше будет concatMap, чтобы дожидаться когда бэк пропатчит данные в первый раз, а потом отправлять второй запрос, чтобы сохранять консистентность данных (конечно это больше задача бэкенда, но иногда легче это делать на фронте, что не очень Юзер Френдли конечно)
В случаях где порядок выполнения запросов не важен, можно использовать mergeMap, он никого не ждет и с каждым новым значением в основном потоке, открывает новую подписку, но в данном случае сложнее следить за текущим состоянием (например loading)
Разбор примера
- так как нет никаких параметров (фильтры, сортировка, пагинация), то нет смысла делать несколько запросов для загрузки одних и тех же данных
- Добавление новых продуктов не требует жесткого порядка, нам без разницы какой запрос на добавление нового продукта выполнится раньше, первый или второй, главное чтобы они добавились, поэтому mergeMap
- Для сохранение консистентности данных, для апдейта продукта используется concatMap, на самом деле реализация здесь не очень хорошая, так как concatMap будет использоваться для всех продуктов, а не для единственного, но если мы будем обновлять один и тот же продукт, существует вероятность, что второй запрос обработается раньше и данные из первого запроса это перетрут (так как на сервере конкурентные потоки и если ими плохо управляют, то такая ситуация вполне возможна), соответственно понимаем, что порядок в данном случае важен, поэтому используется concatMap
- Ну как и во втором пункте, при удалении продуктов, нам не важно в каком порядке выполнятся запросы на удаление продуктов, поэтому можем пускать их в параллель, поэтому mergeMap
Если бы в первом случае была динамическая фильтрация или сортировка, то switchMap был бы лучшим решением Если бы была пагинация в виде lazy loading, то ее обычно выносят в отдельный эффект и используют concatMap так как в данном случае порядок тоже важен (в случае с сортировкой)