【问题标题】:ngrx - Make sure all http calls are done & storing in the storengrx - 确保所有 http 调用都已完成并存储在商店中
【发布时间】:2019-08-10 07:13:57
【问题描述】:

我想要的简要总结

  • 调用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。但是我不知道当数据存储在 store 中时如何捕获数据。

【问题讨论】:

  • 这是因为您正在传输地图的 http 请求。应该向上移动到原始管道
  • @Clouse24 你能告诉我更多细节吗? “原始管道”在哪里?
  • 看看forkJoin操作符
  • @timdeschryver 我实际上尝试过 forkJoin(在使用 Ngrx 之前我用过很多次)。但是我不知道如何用 forkJoin 解决我的问题。就我而言,我必须调用两个操作。但是我如何使用 forkJoin 并赶上这些操作已完成并将数据保存在商店中?谢谢。

标签: angular store ngrx


【解决方案1】:

我可以使用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 请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 2019-02-14
    • 2021-02-18
    • 1970-01-01
    • 2018-10-06
    相关资源
    最近更新 更多