为了账号安全,请及时绑定邮箱和手机立即绑定

使用 ngrx 效果时避免多个请求

使用 ngrx 效果时避免多个请求

RISEBY 2022-01-01 20:50:08
我想对同一个 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 调用,然后对数据进行处理 1ApiCallsService :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 请求的数据进行两次处理
查看完整描述

2 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

我认为你也可以调度一个getRawDataSuccess动作(执行 1 个 api 调用)


getRawData$ = createEffect(() =>

  this.actions$.pipe(

    ofType(ESchedulesActions.getRawData),

    mergeMap(() =>

      this.apiCallsService.getRawData().pipe(

        map(data => ({ type: ESchedulesActions.GetRawDataSuccess, payload: data })),

        catchError(err => ({ type: ESchedulesActions.GetRawDataError, payload: err }))

      )

    )

  )

);

然后为每个治疗创造一个效果,倾听getRawDataSuccess行动:


getSchedulesByDate$ = createEffect(() =>

  this.actions$.pipe(

    ofType(ESchedulesActions.getRawDataSuccess),

    map((action) => {

      return {

        type: ESchedulesActions.GetSchedulesByDateSuccess,

        payload: action.payload.schedulesByDate,

      }

    })

  )

);


getDirectionsByDate$ = createEffect(() =>

  this.actions$.pipe(

    ofType(ESchedulesActions.getRawDataSuccess),

    map((action) => {

      return {

        type: ESchedulesActions.GetDirectionsByDateSuccess,

        payload: action.payload.directionsByDate,

      }

    })

  )

);

这将是更清洁的 IMO,理论上也将并行运行。


查看完整回答
反对 回复 2022-01-01
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

仅使用一种效果从 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,

        },

      ]),

    ),

  );


查看完整回答
反对 回复 2022-01-01
  • 2 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信