Предотвращение избыточных вызовов API от эффекта NGRX - PullRequest
1 голос
/ 17 октября 2019

Я изучаю, как интегрировать архитектуру Redux в приложение Angular, используя библиотеку NGRX, и столкнулся с интересной проблемой, которая меня интересовала. Мне было интересно, как я могу предотвратить множественные и избыточные вызовы API к серверу, когда несколько компонентов запускают действие LoadApps одновременно.

У меня есть следующие редуктор и эффект:

export function appsReducer(state = initialState, action: AppsActions): AppsState {
    switch (action.type) {
        case AppsActionTypes.LoadApps:
            return {
                ...state,
                pending: true,
                data: []
            };

        case AppsActionTypes.LoadAppsSuccess:
            return {
                ...state,
                pending: false,
                data: action.payload
            };

        default:
            return state;
    }
}
@Effect()
    loadApps = this.actions.pipe(
        ofType(AppsActionTypes.LoadApps),
        concatMap(() => this.appService.getApps().pipe(
            switchMap((res: App[]) => {
                return [new LoadAppsSuccess(res)];
            })
        ))
    );

загружает список объектов приложения из моего API. Если в моем угловом приложении есть два родственных компонента, например, навигация по боковой панели, и компонент навигации по верхней панели, для каждого из которых требуется список приложений, то оба они будут запускать действие LoadApps в своих методах OnInit, что приведет к двумточно такого же вызова API к серверу.

Если эффект получает ожидающий логический тип из состояния, чтобы убедиться, что он не соответствует действительности перед запуском другого запроса API, мне кажется, второй вызов эффектамог уже запуститься до того, как ожидающий установится в true.

Предоставляет ли NGRX какой-то механизм для этого?

1 Ответ

4 голосов
/ 17 октября 2019

Попробуйте использовать exhaustMap.

@Effect()
loadApps = this.actions.pipe(
    ofType(AppsActionTypes.LoadApps),
    exhaustMap(() => this.appService.getApps()),
    map(res => [new LoadAppsSuccess(res)])
);

exhaustMap будет игнорировать любые входящие события до тех пор, пока не будет завершено наблюдение в выхлопной карте. https://www.learnrxjs.io/operators/transformation/exhaustmap.html

...