You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJS问题:SpinnerService最后一次设true后20秒自动重置为false

解决SpinnerService自动重置加载状态的问题

问题背景

现有Angular加载状态服务SpinnerService,用于控制全局加载动画,需求是:当最后一次调用showLoader()(即isLoading$设为true)后,若20秒内无新的true状态设置,自动将isLoading$重置为false。

原尝试代码仅能触发第一次true状态的超时,后续新的true无法重置计时器,原因是timeout操作符在第一次超时后会直接终止订阅,且未处理新事件到来时重置计时器的逻辑。

正确实现方案

利用switchMap+timer组合实现"每次收到true就重启20秒计时器"的逻辑,同时添加内存泄漏防护:

import { Injectable, OnDestroy } from '@angular/core';
import { BehaviorSubject, Observable, timer, Subject } from 'rxjs';
import { filter, switchMap, takeUntil, throttleTime, shareReplay } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class SpinnerService implements OnDestroy {
  public throttleTime: number = 10;
  public isLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
  private destroy$ = new Subject<void>();

  constructor() {
    this.setupAutoHideTimer();
  }

  public showLoader(): void {
    this.isLoading$.next(true);
  }

  public hideLoader(): void {
    this.isLoading$.next(false);
  }

  public get isLoadingAPIVal$(): Observable<boolean> {
    return this.isLoading$.pipe(
      throttleTime(this.throttleTime),
      shareReplay()
    );
  }

  private setupAutoHideTimer(): void {
    this.isLoading$
      .pipe(
        // 只关注true状态的变更
        filter(val => val),
        // 每次收到true,就启动一个20秒的定时器;新的true会取消之前的定时器并重启
        switchMap(() => timer(20000)),
        // 服务销毁时终止订阅,避免内存泄漏
        takeUntil(this.destroy$)
      )
      .subscribe(() => {
        // 超时后重置为false
        this.isLoading$.next(false);
      });
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
    this.isLoading$.complete();
  }
}

关键逻辑解释

  • filter(val => val):仅处理isLoading$变为true的事件,忽略false状态
  • switchMap(() => timer(20000)):核心逻辑,每次收到true时创建20秒定时器流;若定时器触发前收到新true,switchMap会取消旧定时器并重启新的,实现计时器重置
  • takeUntil(this.destroy$):服务销毁时自动取消订阅,防止内存泄漏
  • 抽离setupAutoHideTimer方法,让代码结构更清晰

内容的提问来源于stack exchange,提问作者byCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:35:22