개발/Node & Javascript
[RXJS] Hot Observable vs Cold Observable
말고기
2022. 7. 10. 18:58
728x90
반응형
개요
- Hot 생성자의 경우에는 하나의 생성자에서 여러개의 구독자가 붙을 수 있다. ( anycast )
- Cold의 경우 생성자는 구독할 때마다 각각의 타임라인에서 생성된다. ( unicast )
- Hot의 경우 구독을 하더라도, 처리가 이루어지지 않을 수 있다.
- 기본적으로 Observable은 Cold이다.
- 따라서 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
반응형