Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 릿코드
- alexnet
- 스택
- 포인터
- 코딩테스트
- 자료구조
- 연결리스트
- 배열
- GraphQL
- 타입스크립트
- 알고리즘
- 해시테이블
- 웹팩
- vue3
- 자바스크립트
- pytorch
- 브라우저
- 컨테이너
- 프로세스
- C
- 프론트엔드
- 큐
- 이진탐색
- cors
- RxJS
- APOLLO
- 프로그래머스
- Machine Learning
- RT scheduling
- 연결 리스트
Archives
- Today
- Total
프린세스 다이어리
[RxJS] Observable 스트림의 흐름을 합치는 3가지 방법 merge(), concat(), switch() 본문
728x90
회사 FE 스터디때 내 차례에서 발표한 내용 정리
옵저버블을 하나로 합치지 않는다면?
예: 마우스와 터치 동작에 대한 각각의 옵저버블
const mouseUp$ = Rx.Observable.fromEvent(document, 'mouseup');
const touchEnd$ = Rx.Observable.fromEvent(document, 'touchend');
이 2개의 옵저버블을 개별적으로 구독할 수는 있겠지만 한계점이 있다.
- 동일한 코드일 가능성이 큰 구독 영역이 두 개 존재
- 둘 사이에 공유되어야 하는 모든 코드는 외부 공유 상태가 필요.
- 두 개의 구독을 추적해야 해서 잠재적인 메모리 누수 영역 하나 더 생김
→ 둘은 유사한 이벤트를 방출하기 때문에, 단일 코드 블록으로 두 구독을 관리하는 게 낫다.
1. merge()
스트림을 이벤트 방출되는 대로 병합하는 연산자. 두 이벤트에서 OR 연산자를 수행하는 것과 같다.
// 정적 메서드 형식
merge(source1$, source2$, ...)
// 인스턴스 형식
source1$.merge(source2$).merge(...)
(1) Don't
Rx.Observable.merge(mouseUp$, touchEnd$)
.do(event => console.log(event.type))
.map(event => {
switch(event.type) {
case 'touchend':
return {left: event.changedTouches[0].clientX,
top: event.changedTouches[0].clientY};
case 'mouseup':
return {left: event.clientX,
top: event.clientY};
}
})
.subscribe(obj =>
console.log(`Left: ${obj.left}, Top: ${obj.top}`));
→ 타입 판별하려고 더 많은 코드를 도입하는 건 병합의 목적에 맞지 않음. if/else, switch문 지양해야.
(2) Do
const conformantMouseUp$ = mouseUp$.map(event => ({
left: event.clientX,
top: event.clientY
}));
const conformantTouchEnd$ = touchEnd$.map(event => ({
left: event.changedTouches[0].clientX,
top: event.changedTouches[0].clientY,
}));
Rx.Observable.merge(conformantMouseUp$, conformantTouchEnd$)
.subscribe(obj =>
console.log(`Left: ${obj.left}, Top: ${obj.top}`));
→ 병합 전에 데이터를 미리 정규화하여 merge() 이후 조건부 로직 불필요.
(3) Quiz
다음 두 스트림에 대해 merge를 한다면 마지막 구독 시 콘솔에 어떻게 찍힐까?
const source1$ = Rx.Observable.of(1, 2, 3);
const source2$ = Rx.Observable.of("a", "b", "c");
Rx.Observable.merge(source1$, source2$).subscribe(console.log);
- 답: 1 2 3 a b c
- 데이터를 동기로 불러오기 때문
2. concat()
한 스트림이 완료된 후 다음 스트림을 구독하는 연산자. 순서를 지켜야됨
const source$ = concat(...streams);
(1) Quiz
마우스업 이벤트를 50개만 취했을 때, 마우스 이벤트가 50회 방출되는 동안의 터치 이벤트는 콘솔에 찍힐까?
Rx.Observable.concat(mouseUp$.take(50), touchEnd$).subscribe((event) =>
console.log(event.type)
);
- 답: 누락된다.
- take로 50개 이벤트만 취해서 mouseUp 이벤트를 유한하게 만들면, 구독자는 50개의 mouseUp 이후에 touchEnd를 보고, 이전의 터치 이벤트는 누락됨
3. switch()
새 observable이 들어오면 이전 observable 구독을 멈추고 새로운 것만 구독하는 연산자
Rx.Observable.fromEvent(document, "click")
.map((click) => Rx.Observable.range(1, 3))
.switch()
.subscribe(console.log);
- 네트워크 요청 처리 후 이전 요청이 나중에 도착해서 오래된 데이터가 새로운 데이터 덮어씌우는 거 방지
728x90
'FE' 카테고리의 다른 글
DOM이 무엇인가? Virtual DOM이란? 리액트에서의 DOM은? (0) | 2022.05.17 |
---|---|
[RxJS] 중첩 Observable을 처리하는 3가지 방법 - mergeMap(), concatMap(), switchMap() (0) | 2022.02.28 |
프로미스 후속 처리 메서드(resolve, reject, all, race, allSettled) 정리 (0) | 2022.01.29 |
[Storybook] 스토리북 mdx 기본틀 잡기 (0) | 2022.01.28 |
[Storybook] 스토리북에서 vue svg파일 import 하는법 (0) | 2022.01.27 |
Comments