ngrx - 确保所有http调用都已完成并存储在商店中

问题描述 投票:0回答:1

我想要的简要总结

  • 打电话给api 1
  • 打电话给api 2
  • 等到这些数据保存在store
  • 通过effect级别获取这些数据

描述

我想做的只是等到某些操作正确完成并存储在商店中。然后运行下一个。

例如,

@Effect()
  getData1$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.getData1Action),
    switchMap(action => {  // Simply call an api and save data in the store by calling GetData1Success.
      this.httpClient.get(...)
      .pipe(
        map((result) => new GetData1Success(result))
      )
    })
  );
@Effect()
  someEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.UserLogIn),
    flatMap(_ => {  // get first data
      this.store.dispatch(new getData1());
      return of(_);
    }),
    flatMap(_ => {  // get second data
      this.store.dispatch(new getData2());
      return of(_);
    }),
    switchMap(action => { // run final action
      return [new finalAction()];
    }),
    catchError(() => of(new finalActionFailure()))
  );

然后finalAction()被执行,

@Effect()
  finalEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.FinalActionAction),
    switchMap(action => {
      this.store.pipe(select(fromData.data1)).subscribe(data1 => {this.data1 = data1});
      this.store.pipe(select(fromData.data2)).subscribe(data1 => {this.data2 = data2});

  // this.data1, this.data2 are empty...

      return [new finalAction()];
    })
  );

someEffect$中,当http调用成功完成时,getData1getData2都在调用http请求和存储。

问题是它不会等到数据保存在商店中。只是finalAction被执行。

我理解为什么因为flatMap等到getData1完成。但不是GetData1Success

在这种情况下,如何在finalEffect$时刻正确地从商店获取数据?

谢谢。

编辑1:我已经尝试过使用forkJoin。但我不知道如何在存储在商店中时捕获数据。

angular store ngrx
1个回答
0
投票

我可以通过使用forkJoin来解决。但不确定这是否是一种干净的方式。

让我知道你的意见。

所以,我的解决方案是修改上面的第二个代码。

@Effect()
  someEffect$: Observable<Action> = this.actions$.pipe(
    ofType(AuthActionTypes.UserLogIn),
    switchMap(_ => {
      const data1 = this.httpClient.get(...);
      const data2 = this.httpClient.get(...);

      return forkJoin(data1, data2).pipe(
        tap(
         result => {
          // Here update data to the store.
          this.store.dispatch(GetData1Success(result[0]));
          this.store.dispatch(GetData2Success(result[1]));
         }

        )
      )

    }),
    switchMap(action => { // run final action
      return [new finalAction()];
    }),
    catchError(() => of(new finalActionFailure()))
  );

我已经有一个名为GetData1的动作获取data1,但我无法在我的情况下使用此动作,因为我不知道如何抓住data1保存在store中的那一刻。

并最终使用forkJoinswitchMap手动调用http请求。

© www.soinside.com 2019 - 2024. All rights reserved.