首页 > 解决方案 > 使用ngrx效果时避免多次请求

问题描述

我想对同一个 api 调用数据进行两次处理。

我有第一个效果:

loadSchedulings$ = createEffect(() =>
  this.actions$.pipe(
    ofType(ESchedulesActions.GetSchedulesByDate),
    mergeMap(() =>
      this.apiCallsService.getSchedulings().pipe(
        map(trips => ({ type: ESchedulesActions.GetSchedulesByDateSuccess, payload: trips })),
        catchError(() => EMPTY)
      )
    )
  )
);

我调用getSchedulings服务方法进行 api 调用,然后对数据进行处理 1

ApiCalls 服务:

getSchedulings() {
  return this.http.get<ISchedules>(this.SchedulingByDateLocal2).pipe(
      ...
      return groupByDate;
    })
  );
}

我想对同一数据源进行第二次处理。(原始数据来自 api )但与第一个并行,因为它们是独立的

所以按照逻辑我创造了第二个效果

loadDirections$ = createEffect(() =>
  this.actions$.pipe(
    ofType(ESchedulesActions.GetSchedulesByDate),
    mergeMap(() =>
      this.apiCallsService.getDirections().pipe(
        map(trips => ({ type: ESchedulesActions.GetDirectionsByDateSuccess, payload: directions})),
        catchError(() => EMPTY)
      )
    )
  )
);

然后在 apiCallService 我应该有一个方法

getDirections() {
  return this.http.get<ISchedules>(this.SchedulingByDateLocal2).pipe(
      ...
      return groupByDirections;
    })
  );
}

这里的问题是我将对相同的数据有两个请求。

总结实际的工作流程:

LoadSchedulings(效果)==> loadSchedulings(服务)==> API调用==>处理1 LoadDirections(效果)==> loadDirections(服务)==>(相同)API调用==>处理2

所以我只想将第一个 api 请求的数据用于两次处理

更新:根据 Manuel Panizzo 的回应,我应该有这样的东西吗?

getRawData() {
  return this.http.get<ISchedules>(this.SchedulingByDateLocal2)
}

效果.ts

loadSchedulings$ = createEffect(() =>
  this.actions$.pipe(
    ofType(ESchedulesActions.getRawData),
    pipe((data) =>
      this.apiCallsService.getSchedulings(data).pipe(
        map(trips => ({ type: ESchedulesActions.GetSchedulesByDateSuccess, payload: trips })),
        catchError(() => EMPTY)
      )
    ),
    pipe((data) =>
      this.apiCallsService.getDirections(data).pipe(
        map(directions=> ({ type: ESchedulesActions.GetDirectionsByDateSuccess, payload: directions})),
        catchError(() => EMPTY)
      )
    ),
  )
);

标签: javascriptangularreduxrxjsngrx

解决方案


仅使用一种效果从 API 获取原始数据并将其放入您的商店,然后创建两个不同的选择器来应用您的 groupByDirections 和 groupByDate 逻辑。

或者将 groupByDirections 和 groupByDate 逻辑提取到效果。在你的效果中创建一个管道,应用这两种逻辑并在相同的效果中调度两个动作

更新:

如果你想执行两个动作试试这个:

  loadSchedulings$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ESchedulesActions.getRawData),
      mergeMap(action => this.apiCallsService.getRawData()),
      map(rawApiData => {
        const groupByDate = {}; // do your logic with rawApiData
        const groupByDirections = {}; // do your logic with rawApiData
        return { groupByDate, groupByDirections };
      }),
      mergeMap(groupedData => [
        {
          type: ESchedulesActions.GetDirectionsByDateSuccess,
          payload: groupedData.groupByDirections,
        },
        {
          type: ESchedulesActions.GetSchedulesByDateSuccess,
          payload: groupedData.groupByDate,
        },
      ]),
    ),
  );

推荐阅读