Hot Observable & Cold Observable

checkcccc·2021년 2월 12일
0

Observable은 특성에 따라 크게 Hot Observable, Cold Observable 2가지로 나뉜다.

Cold Observable은 아래의 특성을 갖는다.

  • 구독하는 순간부터 데이터를 전달하기 시작
  • 구독할때마다 스트림을 생성하기 때문에 데이터는 독립된 영역을 갖게된다.
  • 일반적인 Observable들이 Cold Observable이다
  • 유니캐스트(1:1)

Hot Observable은 아래의 특성을 갖는다.

  • 구독과 상관없이 중간부터 전달하기 시작
  • 데이터를 공유한다.
  • Subject가 이에 해당된다.
  • 멀티캐스트(1:N)

예제

Cold

const keyup$ = fromEvent(document.getElementById('search'), 'keyup').pipe(
  map(v => v.target.value),
  distinctUntilChanged(),
  tap(v => console.log('from keyup$', v)),
);

const subject = new Subject();

const user$ = keyup$.pipe(
  tap(v => console.log('from user$', v)),
).subscribe();

const reset$ = keyup$.pipe(
  tap(v => console.log('from reset$', v)),
).subscribe();

// Observable을 구독하기때문에 각각의 독립된 영역을 갖는다.
// from keyup$ vvvvd
// from user$ vvvvd
// from keyup$ vvvvd
// from reset$ vvvvd

Hot

  • Subject를 바인딩해서 풀어내는 방식과 Observable을 Connectable Observable로 변환하여 풀어가는 방식이 있다.
  • Subject의 경우 데이터를 변경하는것도 가능하니 가급적이면 외부에 노출하는 방법은 추천하지 않는다.
  • Observable의 데이터를 공유해야되는 경우 Connectable Observable로 변환하는 것이 유용하다.
// subject를 이용하는 방법
const keyup$ = fromEvent(document.getElementById('search'), 'keyup').pipe(
  map(v => v.target.value),
  distinctUntilChanged(),
  tap(v => console.log('from keyup$', v)),
);

const subject = new Subject();

const user$ = subject.pipe(
  tap(v => console.log('from user$', v)),
).subscribe();

const reset$ = subject.pipe(
  tap(v => console.log('from reset$', v)),
).subscribe();

keyup$.subscribe(subject);
// Connectable Observable을 이용하는 방법
// Observable -> Connectable Observable 로 전환
// Cold -> Hot
const keyup$ = fromEvent(document.getElementById('search'), 'keyup').pipe(
  map(v => v.target.value),
  distinctUntilChanged(),
  tap(v => console.log('from keyup$', v)),
  publish(),
);

const user$ = keyup$.pipe(
  tap(v => console.log('from user$', v)),
).subscribe();

const reset$ = keyup$.pipe(
  tap(v => console.log('from reset$', v)),
).subscribe();

// Connectable Observable의 경우
// connect 메서드를 실행시켜주면 동작을 시작한다.
keyup$.connect();

Connectable Observable 사용시 주의점

connect를 사용하는 경우 unsubscribe도 꼭해줘야한다. 메모리 누수가 있을 수 있기 때문이다.

connect와 unsubscribe를 간편하게 해줄 수 있는 기능을 제공하고 있다.

refCount메서드다.

위의 코드에서 unsubscribe를 하지 않는 경우 메모리 누수가 발생하게 된다.

unsubscribe를 빼먹는건 자주 발생하는 일이다. refCount를 사용하여 확인해보자.

connect 메서드는 삭제한다.

const keyup$ = fromEvent(document.getElementById('search'), 'keyup').pipe(
  map(v => v.target.value),
  distinctUntilChanged(),
  tap(v => console.log('from keyup$', v)),
  publish(),
	refCount(),
);

const user$ = keyup$.pipe(
  tap(v => console.log('from user$', v)),
).subscribe();

const reset$ = keyup$.pipe(
  tap(v => console.log('from reset$', v)),
).subscribe();

publish와 refCount를 합쳐서 share 메서드를 제공한다.

const keyup$ = fromEvent(document.getElementById('search'), 'keyup').pipe(
  map(v => v.target.value),
  distinctUntilChanged(),
  tap(v => console.log('from keyup$', v)),
  share(),
);

0개의 댓글

관련 채용 정보