【问题标题】:NgRx effect only listens to last returned observable, ignores any previous returned observableNgRx effect 只监听最后返回的 observable,忽略任何之前返回的 observable
【发布时间】:2019-10-09 14:05:46
【问题描述】:

我正在将我的应用程序同步到 Firestore,并监听更改。当应用程序启动时,它会立即向我的商店发送几个操作,以添加文档。我还有一个 NgRx 效果,等待触发添加操作以执行一些代码,主要是从与操作一起调度的文档的引用中获取其他 2 个文档。我返回一个 forkJoin,效果只完成最后返回的 observable,忽略所有过去的。

我已经尝试了很多 RxJs 操作符去抖动、合并等等,但结果都是一样的。

负责同步文档的服务

fStore.collection<ReservationDocument>('reservations', query =>
            query.where('hotel', '==', hotel.ref)
          )
          .stateChanges()
          .subscribe(actions => {
            actions.forEach(action => {
              switch (action.type) {
                case 'added':
                  console.log(action.payload);
                  store.dispatch(AddReservation({ reservation: action.payload }));
                  break;
                case 'modified':
                  store.dispatch(ModifiyReservation({ reservation: action.payload }));
                  break;
                case 'removed':
                  store.dispatch(RemoveReservation({ reservation: action.payload }));
                  break;
              }
            });
          });

还有效果

getClientAndHotel$ = createEffect(() =>
    this.actions$.pipe(
      ofType(ADD_RESERVATION),
      switchMap(
        (addReservation: {
          reservation: DocumentChange<ReservationDocument>;
        }) => {
          console.log('hello');
          return forkJoin([
            (addReservation.reservation.doc.get(
              'client'
            ) as DocumentReference).get(),
            (addReservation.reservation.doc.get(
              'hotel'
            ) as DocumentReference).get()
          ]).pipe(
            map(
              result => {
                console.log(addReservation.reservation.doc.ref.path);
                return {
                  type: UPDATE_RESERVATION,
                  client: ClientFromDocumentData(
                    result[0].data() as ClientDocument,
                    result[0].ref
                  ),
                  hotel: HotelFromDocumentData(
                    result[1].data() as HotelDocument,
                    result[1].ref
                  ),
                  reservation: addReservation.reservation
                };
              }
            )
          );
        }
      )
    )
  );

我希望 forkJoin 完成并调度一个动作,但是,无论效果被触发多少次,只有最后一个触发器会调度动作。我怀疑每次触发效果时它都会覆盖订阅,而无需等待前一个完成,但我不知道如何解决这个问题。

【问题讨论】:

  • 尝试在效果中使用mergeMap 而不是switchMap
  • 效果很好,您能否向我解释一下这种操作符的切换发生了什么变化?

标签: angular ngrx angularfire


【解决方案1】:

正如对此问题的评论所述,您应该使用mergeMap 而不是switchMap

switchMap 将取消挂起的请求,而mergeMap 将处理所有请求。如果请求的顺序很重要,请使用concatMap

https://rxjs-dev.firebaseapp.com/api/operators/mergeMap

https://rxjs-dev.firebaseapp.com/api/operators/switchMap

https://rxjs-dev.firebaseapp.com/api/operators/concatMap

【讨论】:

    猜你喜欢
    • 2019-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 2017-01-29
    相关资源
    最近更新 更多