2

我有一个 flatMap ,目的是发出两个动作:

export default function searchForPartner(action$, store) {
  return action$.ofType(statusActions.SEARCH_FOR_PARTNER)
    .filter(() => store.getState().user.signedIn)
    .delay(2000)
    .flatMap(() => [
      carouselActions.slideTo(config.CAROUSEL_SLIDES.CONFIRM_CHAT),
      statusActions.foundPerson(),
    ])
    .takeUntil(action$.ofType(carouselActions.TAP_CANCEL))
};

但是,takeUntil是在错误的位置。它在TAP_CANCEL发射时取消了整个史诗。相反,我只希望它取消内部动作的发射flatMap。我该怎么做?

=== 更新 ===

我愚弄了它,这似乎有效?但我不喜欢有 2 个计时器:

export default function searchForPartner(action$, store) {
  return action$.ofType(statusActions.SEARCH_FOR_PARTNER)
    .filter(() => store.getState().user.signedIn)
    .mergeMap(() =>
      Observable.merge(
        Observable.timer(2000)
          .map(() => carouselActions.slideTo(config.CAROUSEL_SLIDES.CONFIRM_CHAT)),
        Observable.timer(2000)
          .map(() => statusActions.foundPerson())
      )
      .takeUntil(action$.ofType(carouselActions.TAP_CANCEL))
    )
};
4

1 回答 1

5

你会想要将delayand the隔离takeUntil到内部的 Observable 中,最重要的是你启动delay计时器,然后takeUntil是它,这样如果有人取消它,你肯定会听——如果你delay在外面,你不会还没听取消操作!这是微妙的,但重要的是要理解为什么。

export default function searchForPartner(action$, store) {
  return action$.ofType(statusActions.SEARCH_FOR_PARTNER)
    .filter(() => store.getState().user.signedIn)
    .flatMap(() =>
      Observable.of(
        carouselActions.slideTo(config.CAROUSEL_SLIDES.CONFIRM_CHAT),
        statusActions.foundPerson()
      )
        .delay(2000)
        .takeUntil(action$.ofType(carouselActions.TAP_CANCEL))
    );
}

您可能还想考虑使用switchMap而不是flatMap(aka mergeMap),因为如果SEARCH_FOR_PARTNER在前一个仍在等待时另一个进来,您将有一个排队的队列。可能不想要你想要的,但你必须打那个电话。

于 2017-03-25T04:10:49.657 回答