RxJS ์ž…๋ฌธ

RxJS๊ฐ€ ์ฒ˜์Œ์ด์‹ ๊ฐ€์š”? ์ด ๋ฌธ์„œ์—์„œ๋Š” RxJS์— ๋Œ€ํ•ด ํŒŒ์•…ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ฃผ์š” ๊ฐœ๋…์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค. ๊ฝ‰ ์žก์œผ์‹œ๊ณ , ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค!

Observable(์˜ต์ €๋ฒ„๋ธ”)์ด ๋ฌด์—‡์ธ๊ฐ€์š”?

์˜ต์ €๋ฒ„๋ธ”์€ ์‹œ๊ฐ„์— ๋”ฐ๋ผ ํ๋ฅด๋Š” ์ŠคํŠธ๋ฆผ(stream) ๋˜๋Š” ๋ฐ์ดํ„ฐ ๊ฐ’์ž…๋‹ˆ๋‹ค. ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ์˜ต์ €๋ฒ„๋ธ”๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€๋งŒ, RxJS์—์„œ์˜ ์ผ๋ฐ˜์ ์ธ ํ™œ์šฉ ์˜ˆ์‹œ๋Š” ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค. ์ด ์ด๋ฒคํŠธ๋Š” ๋งˆ์šฐ์Šค ์ด๋™, ๋ฒ„ํŠผ ํด๋ฆญ, ํ…์ŠคํŠธ ํ•„๋“œ ์ž…๋ ฅ์ด๋‚˜ ๋ผ์šฐํŠธ ๋ณ€๊ฒฝ ๋“ฑ ๋ฌด์—‡์ด๋“  ๋  ์ˆ˜ ์žˆ์ฃ . ์˜ต์ €๋ฒ„๋ธ”์„ ๋งŒ๋“œ๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ๋‚ด์žฅ creation ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด,fromEvent ๋ผ๋Š” ๋‚ด์žฅ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋งˆ์šฐ์Šค ํด๋ฆญ ์ด๋ฒคํŠธ ์˜ต์ €๋ฒ„๋ธ”์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// fromEvent ์—ฐ์‚ฐ์ž import
import { fromEvent } from 'rxjs';

// button ์—˜๋ฆฌ๋จผํŠธ ์ฐธ์กฐ
const button = document.getElementById('myButton');

// button ํด๋ฆญ ์˜ต์ €๋ฒ„๋ธ” ์ƒ์„ฑ 
const myObservable = fromEvent(button, 'click');

์ง€๊ธˆ ์šฐ๋ฆฌ์—๊ฒŒ ์žˆ๋Š” ์ด ์˜ต์ €๋ฒ„๋ธ”์€ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์˜ต์ €๋ฒ„๋ธ”์ด "์ฐจ๊ฐ‘๊ฑฐ๋‚˜", ํ™œ์„ฑํ™”๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์˜ˆ: ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์—ฐ๊ฒฐ). ์ด๊ฒƒ ์ „๊นŒ์ง€๋Š” ๋ง์ด์ฃ ...

Subscription(๊ตฌ๋…)

๊ตฌ๋…์€ ๋ชจ๋“  ๊ฒƒ์„ ์›€์ง์ด๋Š” ์›๋™๋ ฅ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์†์žก์ด๋ฅผ ๋Œ๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋‚˜์˜ฌ ์ค€๋น„๊ฐ€ ๋˜์–ด์žˆ๋Š” ๋ฌผ์ค„๊ธฐ(์˜ต์ €๋ฒ„๋ธ”)์˜ ์ˆ˜๋„๊ผญ์ง€ ๊ฐ™์€ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•ฉ๋‹ˆ๋‹ค. ์˜ต์ €๋ฒ„๋ธ”์˜ ๊ฒฝ์šฐ, ์†์žก์ด๋ฅผ ๋Œ๋ฆฌ๋Š” ์—ญํ• ์€ subscriber(๊ตฌ๋…์ž)์—๊ฒŒ ์ฃผ์–ด์ง‘๋‹ˆ๋‹ค.

๊ตฌ๋…์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด observer(์˜ต์ €๋ฒ„)๋ผ๊ณ  ํ•˜๋Š” ํ•จ์ˆ˜ ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š” subscribe ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋ฐ˜์‘(-ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ) ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// fromEvent ์—ฐ์‚ฐ์ž import
import { fromEvent } from 'rxjs';

// button ์—˜๋ฆฌ๋จผํŠธ ์ฐธ์กฐ
const button = document.getElementById('myButton');

// button ํด๋ฆญ ์˜ต์ €๋ฒ„๋ธ” ์ƒ์„ฑ 
const myObservable = fromEvent(button, 'click');

// ์ด์ œ ๊ฐ ํด๋ฆญ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๋กœ๊ทธ๋ฅผ ์ฐ์–ด๋ด…์‹œ๋‹ค.
const subscription = myObservable.subscribe(event => console.log(event));

์œ„์˜ ์˜ˆ์‹œ์—์„œ myObservable.subscribe() ๋Š”

  1. ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์œ„ํ•œ ๋ฒ„ํŠผ์— ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์„ค์ •ํ•˜๊ณ 

  2. ํด๋ฆญ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ๊ตฌ๋… ๋ฉ”์„œ๋“œ(์˜ต์ €๋ฒ„)์— ์ „๋‹ฌํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

  3. ์ ์ ˆํ•œ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, unsubscribe()๊ฐ€ ํฌํ•จ๋œ ๊ตฌ๋… ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ตฌ๋… ๋ฉ”์†Œ๋“œ๋Š” ์—๋Ÿฌ ๋˜๋Š” ์™„๋ฃŒ ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด map์œผ๋กœ ์ œ๊ณต๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ˆœ ํ•จ์ˆ˜ ํ˜•ํƒœ๋ณด๋‹ค ์ž์ฃผ ์‚ฌ์šฉํ•˜์ง„ ์•Š๊ฒ ์ง€๋งŒ, ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด ์•Œ์•„๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

// ํ•จ์ˆ˜ ๋Œ€์‹ ์—, next, error, complete ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
const subscription = myObservable.subscribe({
  // ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐฉ์ถœ๋˜์—ˆ์„ ๋•Œ
  next: event => console.log(event),
  // ์—๋Ÿฌ
  error: error => console.log(error),
  // ์™„๋ฃŒ ์‹œ ํ•œ ๋ฒˆ ํ˜ธ์ถœ
  complete: () => console.log('complete!')
});

์ค‘์š”ํ•œ ๊ฒƒ์€, ๊ตฌ๋…์€ ๊ฐ๊ฐ ์ƒˆ๋กœ์šด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ง์€, subscribe ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค๋Š” ๊ฒƒ์ด์ฃ .

// addEventListener ํ˜ธ์ถœ
const subscription = myObservable.subscribe(event => console.log(event));

// addEventListener ๋˜ ํ˜ธ์ถœ!
const secondSubscription = myObservable.subscribe(event => console.log(event));

// unsubscribe(๊ตฌ๋… ํ•ด์ œ)๋กœ ์ •๋ฆฌ
subscription.unsubscribe();
secondSubscription.unsubscribe();

๊ธฐ๋ณธ์ ์œผ๋กœ, ๊ตฌ๋…์€ ์˜ต์ €๋ฒ„๋ธ”๊ณผ ์˜ต์ €๋ฒ„ ์‚ฌ์ด์—์„œ ์ผ๋Œ€์ผ, ์ผ๋ฐฉ์  ์†Œํ†ต์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‚˜์œ PR์„ mergeํ•œ ์—ฌ๋Ÿฌ๋ถ„(:์˜ต์ €๋ฒ„)์—๊ฒŒ ์‚ฌ์ˆ˜๋‹˜(:์˜ต์ €๋ฒ„๋ธ”)์ด ์†Œ๋ฆฌ์ง€๋ฅด๋Š” ๊ฒƒ(:๋ฐฉ์ถœ)์ฒ˜๋Ÿผ์š”! ์ด๊ฒƒ์„ Unicasting(์œ ๋‹ˆ์บ์ŠคํŒ…) ์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์ด ์ปจํผ๋Ÿฐ์Šค ๋ฐœํ‘œ ์‹œ๋‚˜๋ฆฌ์˜ค(:ํ•˜๋‚˜์˜ ์˜ต์ €๋ฒ„๋ธ”, ๋งŽ์€ ์˜ต์ €๋ฒ„)๋ฅผ ๋” ์„ ํ˜ธํ•œ๋‹ค๋ฉด, Subject๋ฅผ ์ด์šฉํ•œ Multicasting(๋ฉ€ํ‹ฐ์บ์ŠคํŒ…) ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ทจํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์˜ ๋ฌธ์„œ์—์„œ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”!

์˜ต์ €๋ฒ„์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ์˜ต์ €๋ฒ„๋ธ”์— ๋Œ€ํ•ด ์„ค๋ช…ํ•  ๋•Œ, push ๊ธฐ๋ฐ˜์˜ ๋ชจ๋ธ์ด๋ผ๋Š” ์ ์— ์œ ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†Œ์Šค๋Š” ๊ตฌ๋…์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์ง€๋„, ์‹ ๊ฒฝ์“ฐ์ง€๋„ ์•Š๊ณ  ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ์•„๋ž˜๋กœ ๋ฐ€์–ด๋‚ด๊ธฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

RxJS๋Š” ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ ์œ„์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€๋งŒ, ๊ทธ ์ž์ฒด๋กœ๋„ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. RxJS๊ฐ€ ์ด๋ฒคํŠธ์šฉ loadsh๋ผ๊ณ  ๋ถˆ๋ฆฌ๊ฒŒ ๋œ ์ด์œ ๋Š” RxJS์˜...

Operators(์—ฐ์‚ฐ์ž)

์—ฐ์‚ฐ์ž๋Š” ๊ฐ’์„ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์—ฌ, ๋ณ€ํ˜•๋œ ๊ฐ’๋“ค์˜ ์˜ต์ €๋ฒ„๋ธ”์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Array ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ ์ ์ด ์žˆ๋‹ค๋ฉด ๋Œ€๋ถ€๋ถ„์˜ RxJS ์—ฐ์‚ฐ์ž๋“ค์ด ์ต์ˆ™ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์˜ต์ €๋ฒ„๋ธ”๋กœ๋ถ€ํ„ฐ ๋ฐฉ์ถœ๋œ ๊ฐ’๋“ค์„ ๋ณ€ํ™˜ํ•˜๊ณ  ์‹ถ์„ ๋•Œ, map์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { of } from 'rxjs';
import { map } from 'rxjs/operators';
/*
 *  'of'๋Š” ๊ฐ’์„ ์ˆœ์„œ๋Œ€๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. 
 *  ์ด ์˜ˆ์ œ์—์„œ๋Š”, 1,2,3,4,5๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.
 */
const dataSource = of(1, 2, 3, 4, 5);

// ์†Œ์Šค ์˜ต์ €๋ฒ„๋ธ” ๊ตฌ๋…
const subscription = dataSource
  .pipe(
    // ๋ฐฉ์ถœ๋œ ๊ฐ’์— ๊ฐ๊ฐ 1์„ ๋”ํ•˜๊ธฐ
    map(value => value + 1)
  )
  // ๋กœ๊ทธ: 2, 3, 4, 5, 6
  .subscribe(value => console.log(value));

๋˜๋Š” ํŠน์ •ํ•œ ๊ฐ’์„ ๊ฑธ๋Ÿฌ๋‚ด๊ณ  ์‹ถ์„ ๋•Œ, filter๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { of } from 'rxjs';
import { filter } from 'rxjs/operators';

const dataSource = of(1, 2, 3, 4, 5);

// ์†Œ์Šค ์˜ต์ €๋ฒ„๋ธ” ๊ตฌ๋…
const subscription = dataSource
  .pipe(
    // 2๋ณด๋‹ค ๊ฐ™๊ฑฐ๋‚˜ ํฐ ๊ฐ’๋งŒ ํ—ˆ์šฉ
    filter(value => value >= 2)
  )
  // ๋กœ๊ทธ: 2, 3, 4, 5
  .subscribe(value => console.log(value));

์‹ค๋ฌด์—์„œ ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์—ฐ์‚ฐ์ž๊ฐ€ ์ด๋ฏธ ์กด์žฌ ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. RxJS ์—ฌ์ •์„ ์‹œ์ž‘ํ•˜๋ฉด ์—„์ฒญ๋‚œ ์ˆซ์ž์˜ ์—ฐ์‚ฐ์ž๋“ค์— ์••๋„๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํšจ๊ณผ์ ์ธ ์‹œ์ž‘์„ ์œ„ํ•ด ๋ช‡๋ช‡ ์—ฐ์‚ฐ์ž๋“ค๋งŒ ๋จผ์ € ์ตํ˜€๋„ ๋˜์ฃ . ์–ธ์  ๊ฐ€ ๋ถˆ๊ฐ€ํ”ผํ•˜๊ณ  ์–ด๋ ค์šด ๋ฌธ์ œ๋“ค์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋ฉด, ์—ฐ์‚ฐ์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์œ ์—ฐ์„ฑ์„ ์นญ์ฐฌํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ˆˆ์น˜์ฑ„์…จ๋‚˜์š”? ์œ„์˜ ์˜ˆ์ œ์—์„œ ์—ฐ์‚ฐ์ž๋Š” '์ด๊ฒƒ' ์•ˆ์— ์กด์žฌํ•˜๋Š”๋ฐ์š”....

Pipe

pipe ํ•จ์ˆ˜๋Š” ์˜ต์ €๋ฒ„๋ธ” ๋ฐ์ดํ„ฐ ์†Œ์Šค์—์„œ ์—ฐ์‚ฐ์ž๊นŒ์ง€ ์ด์–ด์ง„ ์—ฐ๊ฒฐ ๋ผ์ธ์ž…๋‹ˆ๋‹ค. ๊ณต์žฅ์˜ ์›์ž์žฌ๊ฐ€ ์™„์ œํ’ˆ์ด ๋˜๊ธฐ ์ „, ์ผ๋ จ์˜ ๊ณผ์ •์„ ๊ฑฐ์น˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์†Œ์Šค ๋ฐ์ดํ„ฐ๋Š” ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘, ํ•„ํ„ฐ๋ง, ๊ทธ๋ฆฌ๊ณ  ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค. pipe๋ฅผ ํฌํ•จํ•˜๋Š” ์˜ต์ €๋ฒ„๋ธ” ์ฒด์ธ ๋‚ด์—์„œ 5๊ฐœ ์ด์ƒ์˜ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด, ๋“œ๋ฌผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์˜ต์ €๋ฒ„๋ธ”๋กœ ๊ตฌํ˜„๋œ ์ž๋™ ์™„์„ฑ ์†”๋ฃจ์…˜์˜ ์š”์ฒญ ๋ฐ ํ‘œ์‹œ ํ”„๋กœ์„ธ์Šค ๋ชจ๋‘ ์—ฐ์‚ฐ์ž๋“ค์„ ์ด์šฉํ•ด ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ํ…์ŠคํŠธ ๋ฐ•์Šค์˜ ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ๋œ ์˜ต์ €๋ฒ„๋ธ”๊ณผ pipe ์ฒด์ธ ์—ฐ์‚ฐ์ž๋“ค
inputValue
  .pipe(
    // 200ms ๊ธฐ๋‹ค๋ฆฌ๊ธฐ
    debounceTime(200),
    // ์—ฐ์†ํ•ด์„œ ๊ฐ™์€ ๊ฐ’์ด ์˜จ๋‹ค๋ฉด, ๋ฌด์‹œํ•˜๊ธฐ
    distinctUntilChanged(),
    // ์š”์ฒญ์ด ํ™œ์„ฑํ™”๋˜์–ด์žˆ๋Š” ๋™์•ˆ ๊ฐ’์ด ์—…๋ฐ์ดํŠธ๋˜๋ฉด ์ด์ „ ์š”์ฒญ์„ ์ทจ์†Œํ•˜๊ณ  ์ƒˆ๋กœ์šด ์˜ต์ €๋ฒ„๋ธ”๋กœ 'switch(์ „ํ™˜)'ํ•ฉ๋‹ˆ๋‹ค.
    switchMap(searchTerm => typeaheadApi.search(searchTerm))
  )
  // ๊ตฌ๋… ์ƒ์„ฑ
  .subscribe(results => {
    // DOM ์—…๋ฐ์ดํŠธ
  });

๊ทธ๋ ‡์ง€๋งŒ ์ƒํ™ฉ์— ์ ์ ˆํ•œ ์—ฐ์‚ฐ์ž๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ข‹์€ ์†Œ์‹ ํ•˜๋‚˜ ์•Œ๋ ค๋“œ๋ฆฌ์ž๋ฉด...

์—ฐ์‚ฐ์ž๋Š” ๊ณตํ†ต๋œ ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

์ ์ ˆํ•œ ์—ฐ์‚ฐ์ž๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋จผ์ € ํ•ด์•ผ ํ•  ์ผ์€ ๊ด€๋ จ๋œ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์†Œ์Šค๋กœ๋ถ€ํ„ฐ ํ•„ํ„ฐ๋ง๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ๊ฐ€์š”? ๊ทธ๋Ÿฌ๋ฉด filtering ์—ฐ์‚ฐ์ž๋“ค์„ ํ™•์ธํ•ด๋ณด์„ธ์š”. ์˜ต์ €๋ฒ„๋ธ” ์ŠคํŠธ๋ฆผ์„ ํ†ต๊ณผํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„ ์† ๋ฒ„๊ทธ๋ฅผ ์ถ”์ ํ•˜๊ณ  ๋””๋ฒ„๊น…ํ•˜๋ ค๊ณ  ํ•˜์‹œ๋‚˜์š”? ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์ค„ utility ์—ฐ์‚ฐ์ž๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž ์นดํ…Œ๊ณ ๋ฆฌ์—๋Š”...

์ด ์—ฐ์‚ฐ์ž๋“ค์€ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ๋“ค๋กœ๋ถ€ํ„ฐ ์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑํ•˜๊ฒŒ๋” ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์ด๋“ , ํŠน๋ณ„ํ•œ ์ƒํ™ฉ์ด๋“ ์ง€ ๊ฐ„์— ์ž์œ ๋กญ๊ฒŒ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ „ํ™˜ํ•˜์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ ์ €์˜ ์Šคํฌ๋กค์— ๋”ฐ๋ผ ์›€์ง์ด๋Š” Progress(์ง„ํ–‰๋ฅ ) ๋ฐ”๋ฅผ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” fromEvent ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํฌ๋กค ์ด๋ฒคํŠธ๋ฅผ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์ฃ .

fromEvent(scrollContainerElement, 'scroll')
  .pipe(
    // ๋‹ค์Œ ๋ฌธ์„œ์—์„œ ์ด ์ฝ”๋“œ์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ๋‹ค๋ค„๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    takeUntil(userLeavesArticle)
  )
  .subscribe(event => {
    // ๊ณ„์‚ฐํ•˜๊ณ , DOM์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ
  });

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ์ƒ์„ฑ ์—ฐ์‚ฐ์ž๋“ค์€ of, from, ๊ทธ๋ฆฌ๊ณ  fromEvent์ž…๋‹ˆ๋‹ค.

์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์˜ต์ €๋ฒ„๋ธ”๋“ค๋กœ๋ถ€ํ„ฐ ์ •๋ณด๋ฅผ ๊ฒฐํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์‚ฐ์ž๋“ค ๊ฐ„์˜ ์ฐจ์ด๋Š” ๋ฐฉ์ถœ๋œ ๊ฐ’์˜ ์ˆœ์„œ, ์‹œ๊ฐ„, ๊ตฌ์กฐ์—์„œ ์ฃผ๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ฐ์ดํ„ฐ ์†Œ์Šค์—์„œ ์—…๋ฐ์ดํŠธ๋œ ๊ฐ’๋“ค์„ ๊ฒฐํ•ฉํ•ด ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์†Œ์Šค ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐฉ์ถœํ‡ผ ๋•Œ๋งˆ๋‹ค, ๊ฐ ์†Œ์Šค์—์„œ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐฉ์ถœ๋œ ๊ฐ’์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
combineLatest(sourceOne, sourceTwo).subscribe(
  ([latestValueFromSourceOne, latestValueFromSourceTwo]) => {
    // ๊ณ„์‚ฐ ์ˆ˜ํ–‰
  }
);

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ์กฐํ•ฉ ์—ฐ์‚ฐ์ž๋“ค์€ combineLatest, concat, merge, startWith, ๊ทธ๋ฆฌ๊ณ  withLatestFrom์ž…๋‹ˆ๋‹ค.

์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์˜ค๋ฅ˜๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ์— ์žฌ์‹œ๋„ํ•˜๋Š” ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์‹คํŒจํ•œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด catchError์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ .

source
  .pipe(
    mergeMap(value => {
      return makeRequest(value).pipe(
        catchError(handleErrorByReturningObservable)
      );
    })
  )
  .subscribe(value => {
    // take action
  });

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์—ฐ์‚ฐ์ž๋Š” catchError์ž…๋‹ˆ๋‹ค.

์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์˜ต์ €๋ฒ„๋ธ” ์†Œ์Šค์—์„œ ๊ฐ’์„ ํ—ˆ์šฉํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€ํ•˜๊ณ , ์ŠคํŠธ๋ฆผ ๋‚ด๋ถ€์— ์ถ•์ ๋œ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ์ˆ ๋“ค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์†Œ์Šค์—์„œ ์ฒ˜์Œ ๋ฐฉ์ถœ๋œ 5๊ฐœ์˜ ๊ฐ’๋งŒ ๊ฐ–๊ธฐ ์œ„ํ•ดtake ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

source.pipe(take(5)).subscribe(value => {
  // ์–ด๋–ค ํ–‰๋™
});

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ํ•„ํ„ฐ๋ง ์—ฐ์‚ฐ์ž๋Š” debounceTime, distinctUntilChanged, filter, take, ๊ทธ๋ฆฌ๊ณ  takeUntil์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ RxJS์—์„œ ์˜ต์ €๋ฒ„๋ธ”์€ "์ฐจ๊ฐ€์šด" ์˜ต์ €๋ฒ„๋ธ”์ด๊ฑฐ๋‚˜ ์œ ๋‹ˆ์บ์ŠคํŠธ(ํ•˜๋‚˜์˜ ๊ตฌ๋…์ž๋‹น ํ•˜๋‚˜์˜ ์†Œ์Šค)์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์˜ต์ €๋ฒ„๋ธ”์„ "๋œจ๊ฒ๊ฒŒ" ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ฉ€ํ‹ฐ์บ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด ์—ฌ๋Ÿฌ ๊ตฌ๋…์ž ๊ฐ„์— ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚˜์ค‘์— ๊ตฌ๋…ํ•œ ๊ตฌ๋…์ž์™€ ํ™œ์„ฑ๋œ ์†Œ์Šค ๋‚ด์—์„œ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐฉ์ถœ๋œ ๊ฐ’์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const source = data.pipe(shareReplay());

const firstSubscriber = source.subscribe(value => {
  // ์–ด๋–ค ํ–‰๋™
});

// ์ž ์‹œ ๋’ค...

// 'secondSubscriber'๋Š” ๊ตฌ๋… ์‹œ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐฉ์ถœ๋œ ๊ฐ’์„ ๊ฐ–๊ฒŒ ๋˜๊ณ , 'firstSubscriber'์™€ ์‹คํ–‰ ์ปจํƒ์ŠคํŠธ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.
const secondSubscriber = source.subscribe(value => {
  // ์–ด๋–ค ํ–‰๋™
});

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ๋ฉ€ํ‹ฐ์บ์ŠคํŒ… ์—ฐ์‚ฐ์ž๋Š” shareReplay์ž…๋‹ˆ๋‹ค.

์—ฐ์‚ฐ์ž ์ฒด์ธ์„ ํ†ต๊ณผํ•˜๋ฉฐ ๊ฐ’์„ ๋ณ€ํ™˜์‹œํ‚ค๋Š” ๊ฑด ํ”ํ•œ ์ž‘์—…์ด์ฃ . ์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์ด ์ ‘ํ•  ๋Œ€๋ถ€๋ถ„์˜ ์ƒํ™ฉ๋“ค์— ๋Œ€ํ•ด ๋ณ€ํ™˜ ๊ธฐ์ˆ ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Redux ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ์ƒํƒœ ๊ฐ์ฒด๋ฅผ ์ถ•์ ํ•˜๋ ค๋ฉด,

source
  .pipe(
    scan((accumulatedState, currentState) => {
      return { ...accumulatedState, ...currentState };
    })
  )
  .subscribe();

๊ฐ€์žฅ ์ž์ฃผ ์“ฐ์ด๋Š” ๋ณ€ํ˜• ์—ฐ์‚ฐ์ž๋Š” concatMap, map, mergeMap, scan, ๊ทธ๋ฆฌ๊ณ  switchMap์ž…๋‹ˆ๋‹ค.

๊ณตํ†ต๋œ ๋™์ž‘์„ ๊ฐ€์ง„ ์—ฐ์‚ฐ์ž๋“ค

๊ฐ™์€ ์นดํ…Œ๊ณ ๋ฆฌ ๋‚ด์— ์—ฐ์‚ฐ์ž๋“ค์€ ๊ณตํ†ต๋œ ๋™์ž‘์„ ๊ณต์œ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์ด ๊ณตํ†ต๋œ ๋™์ž‘๋“ค์„ ์•Œ์•„์ฐจ๋ฆฌ๊ฒŒ ๋˜๋ฉด, ๋จธ๋ฆฟ์†์— ๋‚˜๋งŒ์˜ ์—ฐ์‚ฐ์ž ํŠธ๋ฆฌ ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋Œ€๋ถ€๋ถ„์˜ ์—ฐ์‚ฐ์ž๋Š” ์—ฌ๊ธฐ์— ํฌํ•จ๋˜์ฃ ...

Operators that flatten(ํ‰ํƒ„ํ™” ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž)

๋‹ค์‹œ ์„ค๋ช…ํ•˜์ž๋ฉด, ๋‚ด๋ถ€ ์˜ต์ €๋ฒ„๋ธ”์˜ ๊ตฌ๋…์„ ๊ด€๋ฆฌํ•˜๋Š” ์—ฐ์‚ฐ์ž๋กœ, ๊ฐ’๋“ค์„ ํ•˜๋‚˜์˜ ์˜ต์ €๋ฒ„๋ธ” ์†Œ์Šค๋กœ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค. ์˜ต์ €๋ฒ„๋ธ”์ด๋‚˜ promise ๊ธฐ๋ฐ˜์˜ API์—์„œ HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ, ํ‰ํƒ„ํ™” ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ .

fromEvent(button, 'click')
  .pipe(
    mergeMap(value => {
      // ์ด ๋‚ด๋ถ€ ๊ตฌ๋…์€ mergeMap์œผ๋กœ ๊ด€๋ฆฌ๋˜๊ณ , ์˜ต์ €๋ฒ„์— ์‘๋‹ต๋œ ๊ฐ’์„ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค.
      return makeHttpRequest(value);
    })
  )
  .subscribe(response => {
    // ์–ด๋–ค ํ–‰๋™
  });

ํ‰ํƒ„ํ™” ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋ฅผ ๋™์ž‘์— ๋”ฐ๋ผ ์„ธ๋ถ€์ ์œผ๋กœ ๋‚˜๋ˆ ๋ณด์ž๋ฉด....

Operators that switch(์ „ํ™˜ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž)

์ „๋“ฑ ์Šค์œ„์น˜์ฒ˜๋Ÿผ, switch ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋“ค์€ ์†Œ์Šค์—์„œ ํ˜„์žฌ์˜ ์˜ต์ €๋ฒ„๋ธ”์„ ๊บผ ๋ฒ„๋ฆฌ๊ณ (:๊ตฌ๋… ํ•ด์ œ) ์ƒˆ ์˜ต์ €๋ฒ„๋ธ”์„ ์ผœ ๋ฐฉ์ถœ๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ „ํ™˜ ์—ฐ์‚ฐ์ž๋Š” ํ•œ ๋ฒˆ์— ๋‘˜ ์ด์ƒ์˜ ํ™œ์„ฑํ™”๋œ ์˜ต์ €๋ฒ„๋ธ”์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š์„ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

inputValueChanges
        // ์ด์ „ ์š”์ฒญ/์˜ต์ €๋ฒ„๋ธ”์ด ์ทจ์†Œ๋˜์–ด ์ƒˆ ๊ฐ’์ด ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ ๋งˆ์ง€๋ง‰์— ์ „๋‹ฌ๋œ ์ƒˆ ๊ฐ’๋งŒ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
  .pipe(
    // ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ GET ์š”์ฒญ
    switchMap(requestObservable)
  )
  .subscribe();

์ „ํ™˜ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋“ค์€ switchAll, switchMap, ๊ทธ๋ฆฌ๊ณ  switchMapTo๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Operators that concat(์—ฐ๊ฒฐ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž)

ATM ๊ธฐ๊ณ„ ์•ž์˜ ์ค„์—์„œ, ๋‹ค์Œ ๊ฑฐ๋ž˜๋Š” ์ด์ „ ๊ฑฐ๋ž˜๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ์‹œ์ž‘๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์˜ต์ €๋ฒ„๋ธ” ์šฉ์–ด๋กœ ๋งํ•˜์ž๋ฉด, ์ด์ „ ๊ตฌ๋…์ด ์™„๋ฃŒ๋˜์–ด ํŠธ๋ฆฌ๊ฑฐ๋˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๊ตฌ๋…๋งŒ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ์—ฐ์‚ฐ์ž๋“ค์€ ์œ„์™€ ๊ฐ™์ด ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•œ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜์ฃ .

concat(
  firstObservable,
  // 'firstObservable'์ด ์™„๋ฃŒ๋˜๋ฉด ์‹œ์ž‘
  secondObservable,
  // 'secondObservable'์ด ์™„๋ฃŒ๋˜๋ฉด ์‹œ์ž‘
  thirdObservable
).subscribe(values => {
  // ์–ด๋–ค ํ–‰๋™
});

์—ฐ๊ฒฐ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋“ค์€ concat, concatAll, concatMap, ๊ทธ๋ฆฌ๊ณ  concatMapTo๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Operators that merge(๋ณ‘ํ•ฉ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž)

๊ณ ์†๋„๋กœ์˜ ์ฐจ์„  ํ•ฉ๋ฅ˜ ๋„๋กœ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋ณ‘ํ•ฉ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋Š” ํ•œ ์ฐจ์„ ์—์„œ ํ๋ฅด๋Š” ์—ฌ๋Ÿฌ ํ™œ์„ฑํ™”๋œ ์˜ต์ €๋ฒ„๋ธ”๋“ค์„ ์„ ์ฐฉ์ˆœ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด ์—ฐ์‚ฐ์ž๋“ค์€ ์—ฌ๋Ÿฌ ์†Œ์Šค ์ค‘ ํ•˜๋‚˜์—์„œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ์ž‘์—…์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋ ค๋Š” ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

merge(firstObservable, secondObservable)
  // ์ฒซ ๋ฒˆ์งธ ๋˜๋Š” ๋‘ ๋ฒˆ์งธ ์˜ต์ €๋ฒ„๋ธ”์˜ ๋ฐฉ์ถœ ์‹œ
  .pipe(mergeMap(saveActivity))
  .subscribe();

๋ณ‘ํ•ฉ ๊ธฐ๋ฐ˜์˜ ์—ฐ์‚ฐ์ž๋“ค์€ merge, mergeMap, mergeMapTo ๊ทธ๋ฆฌ๊ณ  mergeAll์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฐ์‚ฐ์ž ๊ฐ„์˜ ๊ธฐํƒ€ ์œ ์‚ฌ์„ฑ

์œ ์‚ฌํ•œ ๋ชฉํ‘œ๋ฅผ ๊ฐ–๊ณ  ์žˆ์ง€๋งŒ ํŠธ๋ฆฌ๊ฑฐ์— ๋‹ค์–‘์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ์—ฐ์‚ฐ์ž๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜๊ณ  ๋‚˜์„œ ์˜ต์ €๋ฒ„๋ธ”์„ ๊ตฌ๋… ์ทจ์†Œํ•˜๊ธฐ ์œ„ํ•ด ์ด๋Ÿฌํ•œ ์—ฐ์‚ฐ์ž๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. take๋Š” n๊ฐœ์˜ ๊ฐ’๋งŒ์„ ์›ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  2. takeLast๋Š” ๋’ค์—์„œ n๊ฐœ์˜ ๊ฐ’๋งŒ์„ ์›ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  3. takeWhile์€ ์ถฉ์กฑํ•ด์•ผ ํ•  ๊ฐ’์˜ ์กฐ๊ฑด์ด ์žˆ์„ ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  4. takeUntil์€ ๋‹ค๋ฅธ ์†Œ์Šค๊ฐ€ ๋ฐฉ์ถœ๋  ๋•Œ๊นŒ์ง€ ํ™œ์„ฑํ™” ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฒ˜์Œ์—” RxJS์˜ ์—ฐ์‚ฐ์ž ์ˆ˜๊ฐ€ ์••๋„์ ์œผ๋กœ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Ÿฌํ•œ ๊ณตํ†ต๋œ ๋™์ž‘๊ณผ ํŒจํ„ด์€ RxJS์˜ ํ•™์Šต ๊ฒฉ์ฐจ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฉ”์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์œผ๋กœ ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ์ฃ ?

์˜ต์ €๋ฒ„๋ธ”์„ ํ†ตํ•œ push ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋”์šฑ ์ต์ˆ™ํ•ด์ง€๋ฉด ์˜ต์ €๋ฒ„๋ธ” ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ๋น„๋™๊ธฐ ๋™์ž‘๋“ค์„ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ณต์žกํ•œ ๋™์ž‘์— ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์†”๋ฃจ์…˜๊ณผ ๋‹ค์–‘์„ฑ์„ ์ œ๊ณตํ•˜์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, ์œ ์ €๊ฐ€ ํ€ด์ฆˆ ์งˆ๋ฌธ์— ๋‹ตํ–ˆ์„ ๋•Œ ์œ ์ €์˜ ํ™œ๋™ ๋‚ด์—ญ์„ ์ €์žฅํ•˜๋Š” ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์ดˆ๊ธฐ ๊ตฌํ˜„์€ ๊ฐ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ €์žฅ ์š”์ฒญ์„ ์‹œ์ž‘ํ•˜๋Š” mergeMap ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

const formEvents = fromEvent(formField, 'click');
const subscription = formEvents
  .pipe(
    map(convertToAppropriateValue),
    mergeMap(saveRequest)
  )
  .subscribe();

์ดํ›„, ์ €์žฅ ์‹œ ์ˆœ์„œ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํŒ๋‹จ๋˜์—ˆ์„ ๋•Œ ์—ฐ์‚ฐ์ž ๋™์ž‘์— ๋Œ€ํ•œ ์ง€์‹์ด ์žˆ๋‹ค๋ฉด, ๋ณต์žกํ•œ ๋Œ€๊ธฐ์—ด ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€์‹ ์— mergeMap ์—ฐ์‚ฐ์ž๋ฅผ concatMap์œผ๋กœ ๊ต์ฒดํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

const formEvents = fromEvent(formField, 'click');
const subscription = formEvents
  .pipe(
    map(convertToAppropriateValue),
    // ์ด์ œ ์ด์ „ ์š”์ฒญ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋‹ค์Œ ์š”์ฒญ์€ ์‹œ์ž‘๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!
    concatMap(saveRequest)
  )
  .subscribe();

๊ณ ์ž‘ ํ•œ ๋‹จ์–ด๋ฅผ ๋ฐ”๊ฟ” ์ด๋ฒคํŠธ ์š”์ฒญ์„ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋งŒ๋“  ๊ฑด, ์•ž์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์— ๋น„ํ•˜๋ฉด ๋น™์‚ฐ์˜ ์ผ๊ฐ์— ๋ถˆ๊ณผํ•˜์ฃ !

๊ณ„์†ํ•˜์„ธ์š”!

RxJS๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฒŒ ๋‘๋ ค์šธ ์ˆ˜ ์žˆ์ง€๋งŒ, ํˆฌ์ž ๊ฐ€์น˜๋Š” ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์•ฝ์†๋“œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…๋“œ๋ฆฐ ๊ฐœ๋… ์ค‘ ์ผ๋ถ€๋ถ„์ด ์—ฌ์ „ํžˆ ๋ช…ํ™•ํ•˜์ง€(๋˜๋Š” ์ดํ•ด๋˜์ง€) ์•Š์•„๋„, ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”! ๊ณง ๋ชจ๋“  ๊ฒŒ ๋ช…ํ™•ํ•ด์งˆ ๊ฑฐ์˜ˆ์š”.

์‚ฌ์ดํŠธ ์™ผ์ชฝ์— ์žˆ๋Š” ์—ฐ์‚ฐ์ž๋“ค์˜ ์˜ˆ์‹œ์™€, ์ž…๋ฌธ์ž๋ฅผ ์œ„ํ•œ ์ž๋ฃŒ๋“ค์„ ํ™•์ธํ•ด๋ณด์„ธ์š”. ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ „๋ฌธ๊ฐ€๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ๋ถ„๋“ค์˜ ์—ฌ์ •์„ ์‘์›ํ•ฉ๋‹ˆ๋‹ค!

Last updated