티스토리 뷰
새로운 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.
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
'프로그래밍 > Angular' 카테고리의 다른 글
Angular app 성능을 최적화하는 10가지 기술 (3) | 2021.07.13 |
---|---|
ViewContainerRef를 사용한 Angular DOM manipulation (0) | 2021.06.19 |
Angular 9와 Ivy (0) | 2020.10.22 |
앵귤러 첫걸음 Ch03 앵귤러 아키텍처 (0) | 2020.03.08 |
What's new in Angular5 (0) | 2018.11.17 |