프로필사진
Observable의 특징 (vs promise, events API, arrays)

2020. 6. 8. 10:49🔴 FE/RxJS

300x250

자바스크립트를 공부하여 observable을 알게 되었는데,
다른 비동기 처리 기술들과 비교해서 obervable이 어떤 특징이 있는지 궁금했다.

다행이도 정리가 잘된 문서가 있어서 공부도 할 겸 번역해보기로 했다.
(번역 오류가 있으면 언제든지 알려주세요, 수정하겠습니다☺)


https://angular.io/guide/comparing-observables

 

Angular

 

angular.io

우리는 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)
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

 

300x250