Сила RxJS. scan + mergeScan = 'Загрузить еще'
Кнопка 'Загрузить еще' (либо автоматическая подгрузка данных при скролле) довольно часто встречается в проектах и обычно решение связано с большим количеством подписок и переменных.
Как всегда, для оптимизации чего либо нам на помощь приходит великий и могучий RxJS, а в данной ситуации конкретно операторы scan & mergeScan.

Код:
readonly loadTrigger$ = new Subject<void>();
private readonly batchSize = 5;
private readonly posts$ = this.loadTrigger$.pipe(
startWith(void 0),
scan((offset) => offset + this.batchSize, -this.batchSize),
mergeScan(
(accPosts: Post[], offset: number) =>
getPosts(offset, this.batchSize).pipe(
map((newPosts) => [...accPosts, ...newPosts]),
),
[] as Post[],
),
);
scan
– калькулятор + хранитель состояния для offset:Управляет состоянием загрузки (текущее смещение)
Начинается с
-batchSize
, чтобы первая загрузка была с0
Увеличивает смещение на
batchSize
при каждом срабатывании
mergeScan
– волшебный оператор для инкрементальной загрузки:Сохраняет массив накопленных постов
Объединяет новые данные с существующими
Корректно обрабатывает параллельные запросы (в отличие от обычного
scan
)
Где полезен этот паттерн?
Постраничные API (пагинация)
Бесконечная прокрутка
Порционная загрузка данных
Любые сценарии накопления асинхронных данных
scan - https://rxjs.dev/api/operators/scan
mergeScan - https://rxjs.dev/api/operators/mergeScan
Больше об Angular - https://t.me/grandgular