티스토리 뷰

새로운 observable  구독하기

switchMap vs concatMap vs mergeMap vs exhaustMap

switchMap: Cancles the current subscription/request and can cause race condition, use for get requests of cancelable requests like searches

새로운 Observable이 방출되면 구독중이던 Observable을 취소하고 새로운 Observable을 구독함

concatMap: Runs subscriptions/requests in order and is less performant, use for get, post and put requests when order is important

새로운 Observable이 방출되어도 구독중이던 Observable을 모두 구독한 뒤 새로운 Observable을 구독함

mergeMap(flatMap): Runs subscriptions/request in parallel, use for get, put, post and delete methods when order is not important

모든 Observable이 방출되는 순으로 병렬로 구독하게 됨

exhaustMap: Ignores all subsequent subscriptions/requests until it completes, use for login when you do not want more requests until the initial one is complete

이전 구독을 완료할 때까지 이후의 모든 구독/요청을 무시함

출처: https://app.pluralsight.com/course-player?clipId=8974b8da-5ae1-4334-a7cc-247956813ea3

xxMap와 xxMapTo의 차이

Simply said, variants with *To will always use the same Observable that needs to be created when the whole chain is created regardless of the values emitted by the chain. They take an Observable as a parameter.

Variants without *To can create and return any Observable only when their source Observable emits. They take a callback as a parameter.

To가 붙은건 체인에서 방출되는 값과 상관없이 전체 체인이 만들어질때 만들어진 같은 Observable만 사용한다

To가 없는건 Observable이 방출될때 리턴된 Observable을 사용한다. 파라미터로 콜백을 가질 수 있음

출처: https://stackoverflow.com/questions/53240090/rxjs-concatmap-vs-concatmapto-mergemap-vs-mergemapto

 

새로운 값으로 시작하기 startWith (valueChanges start with initial value)

//emit (1,2,3)
const source = of(1, 2, 3);
//start with 0
const example = source.pipe(startWith(0)).subscribe(val => console.log(val));
//output: 0,1,2,3

출처: https://www.learnrxjs.io/learn-rxjs/operators/combination/startwith

 

조건에 따라 어떤 Observerble을 구독할지 

iif는 삼항연산자를 캡슐화한다. 

In short, the iif function takes a predicate function as the first argument and two observables as the successive ones.

At the moment of subscription to the stream returned from the iif function, based on the return value of the predicate function,

a client subscribes to either the first (if returns truthy value) or the second (if returns falsy value) provided stream.

The defer creational operator simply takes a stream factory function as its argument and calls it at subscription time.

출처: https://medium.com/javascript-everyday/rxjs-iif-is-not-the-same-as-defer-with-ternary-operator-7cb012903fe7

iif : 간단한 조건문(predicate function)일 때

iif(
  () => condition,			// 조건
  of('first'),				// true라면
  of('second'),				// false라면
).subscribe();

출처: https://rxjs.dev/api/index/function/iif

 

defer : 복잡한 조건문일 때, 구독시에 실행됨

defer(
  () => condition	// 조건
  ? of('first') 	// true라면
  : of('second')	// false라면
).subscribe();

출처: rxjs.dev/api/index/function/defer

 

 

원하는 횟수만큼만 호출하고 싶을 때

first()

from([1,2,3]).pipe(first()).subscribe(val => console.log(val));
// 1
from([1,2,3,4]).pipe(first(val => val%2===0)).subscribe(val => console.log(val));
// 2

take()

of(1,2,3).pipe(take(2)).subscribe(val => console.log(val));
// 1, 2

first()와 take()의 차이

first()는 predicate하기때문에 값이 없을 시 에러가 나지만 take에선 값이 없어도 에러가 나지 않음

출처: https://stackoverflow.com/questions/42345969/take1-vs-first

 

중복 호출방지

distinctUntilChanged()

of(1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4).pipe(
  .distinctUntilChanged()
).subscribe(x => console.log(x));
// 1, 2, 1, 2, 3, 4

출처: https://rxjs-dev.firebaseapp.com/api/operators/distinctUntilChanged 

 

내가 원하는 값으로 방출하기 mapTo()

//emit value every two seconds
const source = Rx.Observable.interval(1000);
//map all emissions to one value
const example = source.mapTo('HELLO WORLD!');
//output: 'HELLO WORLD!'...'HELLO WORLD!'...'HELLO WORLD!'...
const subscribe = example.subscribe(val => console.log(val));

0, 1, 2, ... 대신 HELLO WORLD!, HELLO WORLD!, HELLO WORLD!, ... 이 출력됨

출처:https://www.learnrxjs.io/learn-rxjs/operators/transformation/mapto

 

구독이 끝난 후 무언가 하고 싶다면 finalize()

finalize()와 complete의 차이

finalize()는 observable sequece가 종료될 때 실행되고 complete는 에러가 없이 종료되었을 때 실행된다. -> 중간에 unsubscribe()를 하면 finalize()는 실행되지만 complete는 수행되지 않는다.

import { interval, of } from 'rxjs';
import { take, finalize, delay } from 'rxjs/operators';

//emit value in sequence every 1 second
const source = interval(1000);
//output: 0,1,2,3,4,5....
const example = source.pipe(
  take(5), //take only the first 5 values
  finalize(() => console.log('Sequence complete')) // Execute when the observable completes
);
const subscribe = example.subscribe(val => console.log(val), null, () => console.log('complete'));
// output: 0,1,2,3,4,Sequence complete,complete


subscribe.unsubscribe(); 
// output: Sequence complete

출처: https://www.learnrxjs.io/learn-rxjs/operators/utility/finalize

 

원하는 데이터만 뽑아보기 pluck()

import { from } from 'rxjs';
import { pluck } from 'rxjs/operators';

const source = from([
  { name: 'Joe', age: 30, job: { title: 'Developer', language: 'JavaScript' } },
  //will return undefined when no job is found
  { name: 'Sarah', age: 35 }
]);

//grab names
const example = source.pipe(pluck('name'));
//output: "Joe", "Sarah"

//grab title property under job
const example = source.pipe(pluck('job', 'title'));
//output: "Developer" , undefined

const subscribe = example.subscribe(val => console.log(val));

출처: https://www.learnrxjs.io/learn-rxjs/operators/transformation/pluck

 

방출된 값을 배열로 toArray()

import { interval, of } from 'rxjs';
import { toArray, take, switchMap } from 'rxjs/operators';

interval(100)
  .pipe(take(10), toArray())
  .subscribe(console.log);
  // output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  
  
interval(100)
  .pipe(
    take(10),
    switchMap((x: number) => of(x*100)),
    toArray()
  )
  .subscribe(console.log);
  // output: [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]

출처: https://www.learnrxjs.io/learn-rxjs/operators/transformation/toarray

 

두개의 결과로 받기 partition()

const source = Rx.Observable.from([1,2,3,4,5,6]);
//first value is true, second false
const [evens, odds] = source.partition(val => val % 2 === 0);

const subscribe =
 odds.subscribe(val => console.log(val));
 // output: 1,3,5

const subscribe = Rx.Observable.merge(
 evens
  .map(val => `Even: ${val}`),
 odds
  .map(val => `Odd: ${val}`)
).subscribe(val => console.log(val)); 
 /*
  Output:
  "Even: 2"
  "Even: 4"
  "Even: 6"
  "Odd: 1"
  "Odd: 3"
  "Odd: 5"
*/

출처: https://www.learnrxjs.io/learn-rxjs/operators/transformation/partition?q=empty

댓글
최근에 올라온 글
«   2025/01   »
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 31