【问题标题】:How to finish an active debounceTime in OnDestroy如何在 OnDestroy 中完成活动的 debounceTime
【发布时间】:2020-05-15 16:09:25
【问题描述】:

当用户更改输入字段时,我目前正在保存值。我不想在每次输入新字符时保存该值,所以我使用 rxjs debounceTime 在 3000 毫秒(只是一个示例)没有更改后保存。

this.subscription.add(this.form.controls.inputControl.valueChanges
        .pipe(debounceTime(3000))
        .subscribe(value => {
            // execute HTTP call with value
        }));

ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

如果用户更改了值并且在 3000 毫秒计时器到达之前调用了 OnDestroy,则该调用将不再执行。我想知道是否有办法取消活动计时器并在销毁组件之前执行所有剩余的可观察对象。

编辑:另一个选项可能是用户在有未保存的更改时收到警告。就像谷歌日历在添加新任务和离开页面时所做的那样

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:
    const destroyed = new Subject();
    const isTimerActive = new BehaviorSubject(false);
    
    const stop$ = combineLatest(destroyed, isTimerActive)
      .pipe(
        filter(([isDestroyed, isTimerActive]) => isDestroyed && !isTimerActive)
      );
    
    src$.pipe(
      debounce(
        () => (
          // Now if the component is destroyed, it will not unsubscribe from this stream
          isTimerActive.next(true),
          timer(/* ... */)
        )
      ),
      switchMap(v => makeRequest(v)),
    
      // If the component is destroyed, then after sending this
      // the stream will be unsubscribed
      tap(() => isTimerActive.next(false)),
    
      takeUntil(stop$)
    ).subscribe(/* ... */)
    
    
    ngOnDestroy () {
      this.destroyed.next(true);
      this.destroyed.complete();
    }
    

    重要的是要注意,只有在我们完成所有涉及延迟后发出的值的任务时,才会将计时器声明为非活动状态(isTimerActive.next(false))。

    这是因为如果 destroyedtrue 并且我们立即执行 isTimerActive.next(false),则取消订阅将同步发生,这意味着您将无法使用该值执行任何其他操作.

    【讨论】:

    • 非常好的解决方案。我仍在讨论使用此功能或停用警卫,并警告用户在离开页面时也会收到警告。不过谢谢你的回答!
    猜你喜欢
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-28
    • 2011-06-27
    相关资源
    最近更新 更多