본문 바로가기

프론트엔드/JavaScript

RxJS - 연산자 3

반응형

스트림을 결합하는 연산자들

스트림 결합 연산자

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$ 이런식으로 차례대로 실행된다.

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 연산자들 : 값은 두번째 스트림에서만 발행

mergeMapToconcatMapToswitchMapTo

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)
반응형

'프론트엔드 > JavaScript' 카테고리의 다른 글

RxJS - 연산자 4  (0) 2022.09.12
RxJS - 연산자 2  (0) 2022.09.11
RxJS - 연산자 1  (0) 2022.09.09
RxJS  (0) 2022.09.08