取消 ngrx 效果中的计时器

Cancel a timer in an ngrx effects

我有一个微调器,我希望微调器在显示之前等待 x 秒。但是,如果在微调器等待超时完成期间调用 REQUEST_DEACTIVATE_SPINNER,它应该停止触发 ACTIVATE_SPINNER 操作。也就是我想取消活动计时器。这是我目前所拥有的。

  @Effect() spinnerActive$ = this.actions$
    .ofType(REQUEST_ACTIVATE_SPINNER, REQUEST_DEACTIVATE_SPINNER)
    .switchMap(action => {
      // create a timer and return it active event sent when timer completes
      if (action.type === REQUEST_ACTIVATE_SPINNER) {
        timer$ = Observable.timer(action.payload.delay || 0)
        .switchMap(() =>
          Observable.of({type: ACTIVATE_SPINNER})
        );
      }

      if (action.type === REQUEST_DEACTIVATE_SPINNER) {
        // check to see if a timer is running if it is cancel it
        if (timer$) {
          // cancel the timer
        }
        return Observable.of({type: DEACTIVATE_SPINNER});
      }
    });

有人能告诉我们如何取消返回到 Effect 的计时器吗?

当您需要手动终止计时器时,请在您的订阅上调用 unsubscribe()(抱歉,$timer 本身就是 Observable)。当没有更多的订阅应用于它时,它就会被释放。

您应该能够使用 takeUntil operator.

解决您的问题

当接收到 REQUEST_DEACTIVATE_SPINNER 动作时,您可以使用它来完成 switchMap 中的可观察对象以获得 REQUEST_ACTIVATE_SPINNER 效果。

请注意,现在有两个效果,因为 REQUEST_DEACTIVATE_SPINNER 效果现在独立于 REQUEST_ACTIVATE_SPINNER 效果:

@Effect() spinnerActive$ = this.actions$
  .ofType(REQUEST_ACTIVATE_SPINNER)
  .switchMap(action => Observable
    .timer(action.payload.delay || 0)
    .takeUntil(this.actions$.ofType(REQUEST_DEACTIVATE_SPINNER))
    .switchMap(() => Observable.of({ type: ACTIVATE_SPINNER })
  );

@Effect() spinnerDeactive$ = this.actions$
  .ofType(REQUEST_DEACTIVATE_SPINNER)
  .switchMap(action => Observable.of({ type: DEACTIVATE_SPINNER }));

此外,一些 switchMap 运算符是不必要的,可以替换为 mapTo:

@Effect() spinnerActive$ = this.actions$
  .ofType(REQUEST_ACTIVATE_SPINNER)
  .switchMap(action => Observable
    .timer(action.payload.delay || 0)
    .takeUntil(this.actions$.ofType(REQUEST_DEACTIVATE_SPINNER))
    .mapTo({ type: ACTIVATE_SPINNER })
  );

@Effect() spinnerDeactive$ = this.actions$
  .ofType(REQUEST_DEACTIVATE_SPINNER)
  .mapTo({ type: DEACTIVATE_SPINNER });