IMCAT.DEV
로그인 가입
JavaScript 고급 비동기

JavaScript 고급 비동기 프로그래밍 (RxJS)

JavaScript 고급 비동기 프로그래밍 (RxJS) — 고급

고급 비동기 프로그래밍 (RxJS)

1. 도입 (왜 배워야 하는가)

비동기 프로그래밍은 현대 웹 애플리케이션에서 필수적입니다. 특히, 데이터가 실시간으로 업데이트되고 사용자 인터페이스(UI)가 동적으로 변화하는 환경에서는 더욱 중요합니다. RxJS(리액티브 익스텐션즈 포 자바스크립트)는 이러한 비동기 프로그래밍을 더 간결하고 명확하게 관리할 수 있게 해줍니다.

만약 RxJS를 사용하지 않고 여러 비동기 작업을 처리한다면, 콜백 지옥(callback hell)이나 복잡한 상태 관리 문제에 직면할 수 있습니다. 이는 애플리케이션의 유지 보수성을 저하시킬 뿐 아니라, 버그를 발생시키는 원인이 될 수 있습니다.

2. 핵심 개념 설명

Observable

정의: Observable은 비동기 데이터 스트림을 나타내는 객체입니다. 이는 데이터가 발생할 때마다 이벤트를 발생시킵니다.

비유: Observable은 마치 라디오 방송처럼 생각할 수 있습니다. 방송국(Observable)이 주파수에 맞춰 계속 방송을 하며, 청취자(구독자)는 원하는 방송을 선택해 들을 수 있습니다.

Operator

정의: Operator는 Observable에서 발생하는 데이터를 변형, 필터링, 조합하는 함수입니다.

비유: Operator는 주방에서 요리할 때 사용하는 도구와 같습니다. 식재료(데이터)를 준비하고 조리하여 최종 요리를 만들어내는 역할을 합니다.

Subscription

정의: Subscription은 Observable의 데이터를 실제로 수신하기 위해 구독하는 행위입니다.

비유: Subscription은 라디오 방송을 듣기 위해 주파수를 맞추는 것과 같습니다. 주파수를 맞추지 않으면 방송을 들을 수 없습니다.

용어정의
Observable비동기 데이터 스트림
OperatorObservable에서 데이터 변형 및 필터링 처리
SubscriptionObservable의 데이터를 수신하는 행위

3. 기본 코드 예제

import { Observable } from 'rxjs';

// 1. Observable 정의
const observable = new Observable(subscriber => {
  subscriber.next('Hello');
  subscriber.next('RxJS');
  subscriber.complete(); // Observable 종료
});

// 2. Observable 구독
observable.subscribe({
  next(x) { console.log(x); }, // 데이터를 수신할 때 실행
  complete() { console.log('완료'); } // Observable 종료 시 실행
});

실행 결과:

Hello
RxJS
완료
  • 1행: Observable을 정의합니다. 이 함수는 데이터 흐름을 정의합니다.
  • 2행: subscriber 객체를 통해 데이터를 송출합니다.
  • 3행: Observable이 완료되면 complete() 메서드를 호출합니다.
  • 5행: Observable을 구독합니다.
  • 6행: 데이터가 수신될 때마다 next() 메서드가 실행됩니다.
  • 8행: Observable이 완료되면 complete() 메서드가 호출됩니다.
  • 4. 실전 활용 예제

    예제 1: 쇼핑몰 장바구니

    쇼핑몰에서 장바구니에 상품을 추가할 때, 사용자가 선택한 상품의 수량에 따라 자동으로 가격을 업데이트할 수 있습니다.

    import { fromEvent } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    // 상품 수량을 나타내는 input 요소
    const quantityInput = document.getElementById('quantity');
    
    // 수량 입력 이벤트를 Observable로 변환
    const quantity$ = fromEvent(quantityInput, 'input').pipe(
      map(event => event.target.value) // 수량을 가져옵니다.
    );
    
    // 구독하여 가격을 계산합니다.
    quantity$.subscribe(quantity => {
      const price = 1000; // 상품 가격
      console.log(총 가격: ${quantity * price} 원);
    });

    예제 2: 실시간 검색

    사용자가 검색어를 입력할 때마다 API에서 데이터를 fetch하여 결과를 보여주는 기능을 구현할 수 있습니다.

    import { fromEvent } from 'rxjs';
    import { debounceTime, map, switchMap } from 'rxjs/operators';
    
    // 검색 입력란
    const searchInput = document.getElementById('search');
    
    // 검색 이벤트를 Observable로 변환
    fromEvent(searchInput, 'input').pipe(
      debounceTime(300), // 300ms 대기
      map(event => event.target.value), // 입력값을 가져옵니다.
      switchMap(searchTerm => fetch(https://api.example.com/search?q=${searchTerm})), // API 호출
    ).subscribe(response => response.json().then(data => console.log(data)));

    5. 흔한 실수와 주의사항

    실수 1: Observable을 구독하지 않음

    const observable = new Observable(subscriber => {
      subscriber.next('Hello');
    });
    // 구독하지 않으면 아무것도 실행되지 않음
  • 올바른 코드: 반드시 observable.subscribe()를 호출해야 합니다.
  • 실수 2: 메모리 누수

    Observable이 구독된 상태에서 컴포넌트가 제거되면, 구독을 해제하지 않으면 메모리 누수가 발생할 수 있습니다.

    const subscription = observable.subscribe();
    // 구독 해제 코드가 없음
  • 올바른 코드: 컴포넌트가 제거될 때 subscription.unsubscribe()를 호출해야 합니다.
  • 6. 정리

  • RxJS는 비동기 프로그래밍을 더 간결하고 명확하게 만들어 줍니다.
  • Observable, Operator, Subscription의 개념을 이해하는 것이 중요합니다.
  • 실전에서 활용할 수 있는 패턴을 학습하여 실제 프로젝트에 적용해 보세요.
  • 다음에 학습하면 좋은 주제:

  • RxJS의 Subject와 BehaviorSubject
  • 고급 Operator 사용법 (mergeMap, concatMap 등)
  • 상태 관리 라이브러리와 RxJS 통합 (예: NgRx)