[RXJS] Hot Observable vs Cold Observable

2022. 7. 10. 18:58개발/Node & Javascript

728x90
반응형

개요

  1. Hot 생성자의 경우에는 하나의 생성자에서 여러개의 구독자가 붙을 수 있다. ( anycast )
  2. Cold의 경우 생성자는 구독할 때마다 각각의 타임라인에서 생성된다. ( unicast )
  3. Hot의 경우 구독을 하더라도, 처리가 이루어지지 않을 수 있다.
  4. 기본적으로 Observable은 Cold이다.
  5. 따라서 Hot으로 변경하기 위해서는 Connectable Observable/Flowable로의 변환이 필요하다. (아니면 쉽게 subject를 통해 구현이 가능하다.)

Cold Observable vs Hot Observable

비교 Hot Cold
데이터 배출 구독하지 않아도 계속 배출 구독하지 않으면 배출하지 않음
example 마우스 이벤트, 키보드 이벤트, 시스템 이벤트 웹 요청, 데이터 베이스 쿼리

Examples

기본 함수

const sleep = async function (ms: number): Promise<void> {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

const doBackground = async (count: number, subscriber: Subscriber<number>) => {
  for (let i = 0; i < count; i++) {
    await sleep(1000);

    subscriber.next(i);
  }

  subscriber.complete();
};

const generator = (count: number): Observable<number> => {
  return new Observable( subscriber => {
    console.log('generator called');
    doBackground(count, subscriber).then(console.log).catch(console.error);
    return ;
  });
};

Cold Observable

아래는 개별적으로 Observable을 생성할 수 있는 것을 볼 수 있다.

const observable = from(generator(10))
.pipe(
  bufferCount(1)
)

console.log('not subscribed');
observable.subscribe((item) => console.log('A' + item));;
setTimeout(() => {
  console.log('subscribed');
  observable.subscribe((item) => console.log('B' + item));;
}, 3000);

Hot Observable

1. subject

아래는 subject를 통해서 hot observable을 생성해서 사용한다.

const subject = new Subject<number>();
let i = 0;
setInterval(() => subject.next(i++), 1000);

subject
  .pipe(map(item => item * 2))
  .subscribe((item) => console.log('A' + item));

setTimeout(() => {
  console.log('subscribed');
  subject
    .pipe(map(item => item * 3))
    .subscribe((item) => console.log('B' + item));
}, 3000);

setTimeout(() => {
  console.log('subscribed');
  subject
    .pipe(map(item => item * 5))
    .subscribe((item) => console.log('C' + item));
}, 13000);

2. connectable

아래는 구독 여부와 상관없이 connect()를 호출한 시간부터 데이터를 emit 한다.

const connected = connectable(generator(10));
connected
  .pipe(map(item => item * 2))
  .subscribe((item) => console.log('A' + item));
connected.connect();
setTimeout(() => {
  console.log('subscribed');
  connected
    .pipe(map(item => item * 3))
    .subscribe((item) => console.log('B' + item));
}, 2000);

setTimeout(() => {
  console.log('subscribed');
  connected
    .pipe(map(item => item * 5))
    .subscribe((item) => console.log('C' + item));
}, 13000);
728x90
반응형

'개발 > Node & Javascript' 카테고리의 다른 글

[RXJS] mergeMap, switchMap 차이  (3) 2022.08.21
[Typescript] typescript 연습하기  (5) 2022.07.17
[RXJS] from vs of 차이  (3) 2022.06.27
[Nest.js] graceful shutdown을 구현하자.  (0) 2022.06.12
[RxJS] bufferCount 써보기  (0) 2022.05.08