2020. 6. 8. 10:49ㆍ🔴 FE/RxJS
자바스크립트를 공부하여 observable을 알게 되었는데,
다른 비동기 처리 기술들과 비교해서 obervable이 어떤 특징이 있는지 궁금했다.
다행이도 정리가 잘된 문서가 있어서 공부도 할 겸 번역해보기로 했다.
(번역 오류가 있으면 언제든지 알려주세요, 수정하겠습니다☺)
https://angular.io/guide/comparing-observables
우리는 observable를 promise대신 사용해서 값들은 비동기적으로 전달할 수 있다.
이처럼 observable는 event handler의 역할을 할 수도 있다.
그리고 observable는 여러개의 값들을 전달할 수 있기 때문에 우리는 이를 배열을 만들고 실행하는 데에 사용할 수도 있다.
observable은 다른 대체적인 기술들과는 다르게 실행되는데, 좀 더 중요한 장점들을 지니고 있다.
다른 기술들과 비교해서 어떤 특징이 있는지 알아보자
observable vs promise
observable은 주로 promise와 비교되는데, 둘의 차이점은 아래와 같다 :
- observable은 선언적어서 구독 전에는 계산을 시작하지 않는다. 이와 달리, promise는 생성과 동시에 실행된다.
이러한 차이점으로 인해 observable은 당신이 결과값을 원할 때 실행하고자 하는 코드에 유용하게 쓰인다.
- observable은 여러 값들은 제공하지만 promise는 하나만 제공한다. 따라서 observable은 시간에 따라 여러 값들을 얻는데에 유용하게 사용할 수 있다.
- observable은 chaining과 subscription을 구분짓지만 primise는 .then() 으로 통일한다. 그래서 observable은 시스템의 다른 부분에서 복잡한 변형을 만들어야 할 때 쓰인다.
- observable의 subscribe()는 에러를 처리하는데 사용할 수도 있다. 하지만 promise는 에러들을 자식 promise에게 넘긴다. 따라서 observable는 중심적으로 예측가능한 에러들을 처리하는 데 도움이 된다.
observable vs promise의 동작 정리 표
동작 | observable | promise |
생성 | new Observable ( (observer) => { observer.next(123); }); |
new Promise( (resolve, reject) => { resolve(123); }); |
변형 | obs.pipe(map((value) => value * 2)); | promise.then((value) => value * 2); |
구독 | sub = obs.subscribe( (value) => { console.log(value); }); |
promise.then( (value) => { console.log(value); }); |
구독취소 | sub.unsubscribe(); | Implied by promise resolution |
observable vs events API
observable은 events API를 사용하는 event handler와 매우 유사하다.
둘 다 notification handler를 정의하고, 이를 사용해서 다양한 값들을 전달하는 데에 쓴다.
observable을 구동하는것은 event listener을 추가하는 것과 동일하다.
하나 중요한 차이점은 바로 event을 handler에 넘기기 전에 observable이 event을 변형시킬 수 있도록 설정하는 것이다.
observable으로 event을 헨들링하고 비동기적인 처리를 하면 컨텍스트(ex. HTTP request)의 일관성을 유지하는 데에 큰 도움이 된다.
아래는 observable과 event API를 사용하여 작업을 한 예시들이다.
observable | events API | |
생성 & 취소 | // Setup let clicks$ = fromEvent(buttonEl, ‘click’); // Begin listening let subscription = clicks$ .subscribe(e => console.log('Clicked', e)) // Stop listening subscription.unsubscribe(); |
function handler(e) { console.log('Clicked', e) } // Setup & begin listening button.addEventListener(‘click’, handler); // Stop listening button.removeEventListener(‘click’, handler); |
구독 | observable.subscribe(() => { // notification handlers here }); |
element.addEventListener(eventName, (event) => { // notification handler here }); |
설정 | Listen for keystrokes, but provide a stream representing the value in the input. fromEvent(inputEl, 'keydown').pipe( map(e => e.target.value) ); |
Does not support configuration. element.addEventListener(eventName, (event) => { // Cannot change the passed Event into another // value before it gets to the handler }); |
observable vs arrays
observable은 계속해서 값들을 제공한다. 하지만 배열은 static하게 정해진 값들처럼 만들어진다.
즉, observable은 비동기적이지만 배열은 동기적이라는 것이다.
아래 예시에서 '➞'는 비동기적인 값 전달을 뜻한다.
observable | array | |
Given | obs: ➞1➞2➞3➞5➞7 obsB: ➞'a'➞'b'➞'c' |
arr: [1, 2, 3, 5, 7] arrB: ['a', 'b', 'c'] |
concat() | concat(obs, obsB) ➞1➞2➞3➞5➞7➞'a'➞'b'➞'c' |
arr.concat(arrB) [1,2,3,5,7,'a','b','c'] |
filter() | obs.pipe(filter(v) => v>3) ➞5➞7 |
arr.filter((v) => v>3) [5, 7] |
find() | obs.pipe(find(v) => v>3) ➞5 |
arr.find((v) => v>3) 5 |
findIndex() | obs.pipe(findIndex((v) => v>3)) ➞3 |
arr.findIndex((v) => v>3) 3 |
forEach() | obs.pipe(tap((v) => { console.log(v); })) 1 2 3 5 7 |
arr.forEach((v) => { console.log(v); }) 1 2 3 5 7 |
map() | obs.pipe(map((v) => -v)) ➞-1➞-2➞-3➞-5➞-7 |
arr.map((v) => -v) [-1, -2, -3, -5, -7] |
reduce() | obs.pipe(reduce((s,v) => s+v, 0)) ➞18 |
arr.reduce((s,v) => s+v, 0) 18 |
'🔴 FE > RxJS' 카테고리의 다른 글
BehaviorSubject vs ReplaySubject (1) | 2021.01.16 |
---|---|
RxJS 'startWith'를 좀 더 똑똑하게 사용하는 팁 (0) | 2021.01.05 |
RxJS - 검색 Input 만들기 : debounceTime and distinctUntilChanged (1) | 2020.07.06 |
RxJS를 써야하는 이유!! (2) | 2020.06.25 |