프론트엔드/JavaScript
RxJS - 연산자 3
lifecarelog
2022. 9. 12. 15:30
반응형
스트림을 결합하는 연산자들
스트림 결합 연산자
merge : 두 스트림을 순서관계없이 병합
const { merge, interval, fromEvent } = rxjs
const { map } = rxjs.operators
const interval$ = interval(1000).pipe(map(_ => 'interval'))
const click$ = fromEvent(document, 'click').pipe(map(_ => 'click'))
merge(interval$, click$).subscribe(console.log)
const { merge, interval } = rxjs
const { map, take } = rxjs.operators
const intv1$ = interval(1000).pipe(
map(_ => 'INTERVAL 1'), take(3))
const intv2$ = interval(1000).pipe(
map(_ => 'INTERVAL 2'), take(6))
const intv3$ = interval(1000).pipe(
map(_ => 'INTERVAL 3'), take(9))
const intv4$ = interval(1000).pipe(
map(_ => 'INTERVAL 4'), take(9))
const intv5$ = interval(1000).pipe(
map(_ => 'INTERVAL 5'), take(9))
merge(intv1$, intv2$, intv3$, intv4$, intv5$, 3)
.subscribe(console.log)
- interval$이 1초에 한 번씩 발행되면서 동시에 클릭 이벤트가 발생하면 click$ 스트림도 발행된다.
- interval$과 click$ 을 각각 subscribe하지 않고 merge를 사용해서 한 번에 두 스트림을 구독한 것이다.
- merge에 인자로 N개의 스트림을 넣어주고 마지막에 정수를 넣어주면 해당하는 정수만큼만 merge가 이루어진다.
- merge(intv1$, intv2$, intv3$, intv4$, intv5$, 3)
- intv1$, intv2$, intv3$ 스트림이 먼저 합쳐지고 intv1$이 끝나면 intv2$, intv3$, intv4$ 이런식으로 차례대로 실행된다.
- merge(intv1$, intv2$, intv3$, intv4$, intv5$, 3)
concat : 스트림을 순서대로 이어붙임
const { concat, interval } = rxjs
const { map, take } = rxjs.operators
const intv1$ = interval(1000).pipe(
map(_ => 'INTERVAL 1'), take(3))
const intv2$ = interval(1000).pipe(
map(_ => 'INTERVAL 2'), take(3))
const intv3$ = interval(1000).pipe(
map(_ => 'INTERVAL 3'), take(3))
concat(intv1$, intv2$, intv3$)
.subscribe(console.log)
const { concat, interval, fromEvent } = rxjs
const { map, take } = rxjs.operators
const interval$ = interval(1000).pipe(
map(_ => 'interval'), take(5))
const click$ = fromEvent(document, 'click').pipe(map(_ => 'click'))
concat(interval$, click$).subscribe(console.log)
- 첫 번쨰 스트림이 완전히 끝나면 다음 스트림을 시작하는 것
mergeMap : (mergeAll 참조)
- api 요청을 동시에 요청을 보내서 먼저 오는 순서대로 값을 받는다.
- mergeAll이 원조 ⇒ 단순화 한 것이 mergeMap
const { interval, fromEvent } = rxjs
const { mergeMap, map, take } = rxjs.operators
fromEvent(document, 'click').pipe(
mergeMap(e => interval(1000).pipe(
map(i => e.x + ' : ' + i),
take(5)
))
).subscribe(console.log)
const { of } = rxjs
const { ajax } = rxjs.ajax
const { mergeMap, pluck } = rxjs.operators
of(3, 15, 4, 9, 1, 7).pipe(
mergeMap(keyword => ajax(
`http://127.0.0.1:3000/users/${keyword}`
).pipe(
pluck('response', 'first_name')
)
)
).subscribe(console.log)
const { of } = rxjs
const { ajax } = rxjs.ajax
const { mergeMap, pluck } = rxjs.operators
of(3, 15, 4, 9, 1, 7).pipe(
mergeMap(keyword => ajax(
`http://127.0.0.1:3000/people/${keyword}`
).pipe(
pluck('response', 'first_name')
)
, 3) // 한 번에 3개 스트림만
).subscribe(console.log)
- mergeMap 역시 두 번째 인자로 몇 개의 스트림을 동시 진행할 것인지 설정할 수 있습니다.
concatMap : (concatAll 참조)
- concatAll이 원조 ⇒ 단순화 한 것이 concatMap
- 순서대로 스트림을 이어 붙인다.
const { interval, fromEvent } = rxjs
const { concatMap, map, take } = rxjs.operators
fromEvent(document, 'click').pipe(
concatMap(e => interval(1000).pipe(
map(i => e.x + ' : ' + i),
take(5)
))
).subscribe(console.log)
const { of } = rxjs
const { ajax } = rxjs.ajax
const { concatMap, pluck } = rxjs.operators
of(3, 15, 4, 9, 1, 7).pipe(
concatMap(keyword => ajax(
`http://127.0.0.1:3000/users/${keyword}`
).pipe(
pluck('response', 'first_name')
)
)
).subscribe(console.log)
- mergeMap 예제와 달리 concatMap으로 ajax 요청들을 보내면 늘 동일한 순서로 이름들이 반환됩니다
- concatMap은 스트림이 겹치기 않게 순서대로 발행되고 mergeMap은 여러 스트림을 하나의 스트림으로 합치는 것!!!
- mergeMap과 concatMap의 마블 다이어그램도 위의 각 링크를 클릭하여 확인해보세요!
switchMap : 기준 스트림이 새 값을 발행하면 진행중이던 스트림을 멈춤
const { interval, fromEvent } = rxjs
const { switchMap, map, take } = rxjs.operators
fromEvent(document, 'click').pipe(
switchMap(e => interval(1000).pipe(
map(i => e.x + ' : ' + i),
take(5)
))
).subscribe(console.log)
- 기존 스트림이 끝나기 전에 새로운 스트림이 발생하면 이전 스트림을 끊어내고 새로운 스트림을 발행한다.
~MapTo 연산자들 : 값은 두번째 스트림에서만 발행
mergeMapTo, concatMapTo, switchMapTo
const { interval, fromEvent } = rxjs
const { mergeMapTo, take } = rxjs.operators
fromEvent(document, 'click').pipe(
mergeMapTo(interval(1000).pipe(take(5))),
).subscribe(console.log)
const { interval, fromEvent } = rxjs
const { concatMapTo, take } = rxjs.operators
fromEvent(document, 'click').pipe(
concatMapTo(interval(1000).pipe(take(5))),
).subscribe(console.log)
const { interval, fromEvent } = rxjs
const { switchMapTo, take } = rxjs.operators
fromEvent(document, 'click').pipe(
switchMapTo(interval(1000).pipe(take(5))),
).subscribe(console.log)
반응형