Angular 프로젝트에서 RxJS Observable 제대로 다루기

문제 상황

대시보드 컴포넌트에서 폴링 방식으로 데이터를 갱신하는 기능을 구현했는데, 페이지를 이동했다가 돌아오면 HTTP 요청이 중복으로 발생하는 문제가 있었다. 개발자 도구로 확인해보니 컴포넌트를 벗어났는데도 Observable 구독이 계속 살아있었다.

원인

Angular에서 HTTP 요청은 자동으로 완료되지만, interval이나 수동 Observable은 직접 구독 해제를 해줘야 한다.

export class DashboardComponent implements OnInit {
  ngOnInit() {
    // 문제가 되는 코드
    Observable.interval(3000)
      .switchMap(() => this.http.get('/api/stats'))
      .subscribe(data => this.stats = data);
  }
}

해결 방법

1. Subscription 직접 관리

export class DashboardComponent implements OnInit, OnDestroy {
  private subscription: Subscription;

  ngOnInit() {
    this.subscription = Observable.interval(3000)
      .switchMap(() => this.http.get('/api/stats'))
      .subscribe(data => this.stats = data);
  }

  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

2. takeUntil 패턴 (추천)

export class DashboardComponent implements OnInit, OnDestroy {
  private destroy$ = new Subject<void>();

  ngOnInit() {
    Observable.interval(3000)
      .switchMap(() => this.http.get('/api/stats'))
      .takeUntil(this.destroy$)
      .subscribe(data => this.stats = data);
  }

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

takeUntil 패턴은 여러 구독을 한 번에 정리할 수 있어서 실무에서 더 유용했다.

결론

Angular에서 Observable을 다룰 때는 항상 구독 해제를 염두에 둬야 한다. HTTP 요청은 자동 완료되지만, interval, Subject 등은 명시적 관리가 필요하다. takeUntil 패턴을 기본으로 사용하면 실수를 줄일 수 있다.