타입스크립트 11일차 - RXJS

RXJS

요즘 엄청난 이슈를 몰고 있는 반응형 프로그래밍 모델을 자바스크립트로 만든 라이브러리 입니다.

특히 비동기 코드를 제어하는데 강점이 있으며 수많은 비동기와 함께 해야 하는 자바스크립트와 잘 맞는다네요.

반응형 프로그래밍이란?

위키피디아에서는 다음과 같이 소개하고있네요 Reactive Programming is an asynchronous programming paradigm concerned with data streams and the propagation of change. 대충 번역하면 데이터 스트림 및 변경/전파와 관련된 비동기 프로그래밍 패러다임이다 라고 하는데 무슨소리인지 영..

아무튼 비동기 프로그래밍에서 데이터스트림을 효과적으로 다루기 위해 나온 것이라는 사실은 알 수 있을까요.

특히 이러한 프로그래밍을 사용하기 위해서 옵저버블 패턴, 이터레이터 패턴, 함수형 프로그래밍을 사용하고 있다고 합니다.

덧붙여 리액티브 프로그래밍을 사용하면 코드의 추상화 수준을 높여주기 때문에 우리가 받아야할 이벤트 연관성에만 집중해서 프로그래밍 할 수 있다고 합니다.

간단하게 시작하기

일단 서드파티 라이브러리 이므로 깔아야합니다.

npm install @reactivex/rxjs를 입력해 최신버전을 깝니다.

잘 설치됐는지 테스트를 해봅시다.

1
2
import * as Rx from "@reactivex/rxjs";
Rx.Observable.of("1","2","3").subscribe(v => console.log(v));

해당 코드의 결과는 1,2,3 이렇게 순차적으로 찍힙니다.

간단하게 클릭이벤트도 만들어봅시다.

1
2
var button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'));

이러면 HTML로 버튼하나를 만들어서 클릭했을때 clicked alert이 발생할것입니다.

즉, RxJS에서는 키를 입력할 때마다 데이터가 생성되고 그 데이터를 연산자에 의해 처리하고 이 데이터를 구독해서 재처리함으로써 데이터를 소비하게 됩니다.

그러므로 RxJS 처리의 핵심은 입력된 데이터 스트림을 연산자로 처리해 구독자에게 결과를 전달하는 것입니다.

그럼 책+인터넷을 참고해서 그렇게 중요한 연산자에 대해 알아보겠습니다.

연산자

연산자는 현재 Observable을 기반으로 새롭게 Observable을 생성하는 순수한 함수입니다. 순수한 함수라는 말은 언제나 같은 값을 넣으면 같은 값이 나오는 함수형 프로그래밍에서 자주 쓰이는 말입니다.

아무튼 RxJS에서는 스트림을 처리하기 위해 다음과 같은 부류의 연산자를 제공합니다.

  • Creation Operators
  • Transformation Operators
  • Filtering Operators
  • Combination Operators
  • Multicasting Operators
  • Error Handling Operators
  • Utility Operators
  • Conditional and Boolean Operators
  • Mathematical and Aggregate Operators

Creation Operators

생성연산자는 데이터 스트림을 생성하기 위해 제공합니다. 이벤트나 값을 시퀀스 형태로 생성해줍니다.

대표적으로 create, from, of가 있습니다.

create는 Custom Observable을 생성해 구독자에게 통지하는 기능을 제공합니다.

from은 객체 대부분을 Observable로 변환하는 기능을 가지고 있습니다.

of는 받은 인수를 내보내는 연산자입니다. 무슨말이냐면 처음 예제코드와 같이 받은 인수 1,2,3을 하나씩 구독자에게 내보냅니다.

Transformation Operators

변형 연산자는 말그대로 데이터 스트림을 입력받아 형태를 가공하는 연산자입니다.

대표적으로는 map이 있습니다. 형태도 다양합니다. concatMap, MergeMap, switchMap 등등등…

1
Rx.Observable.from([1,2,3]).map(val => val+10).subscribe(val => console.log(val));

이런 예제 코드가 있다고 하면 입력받는 1,2,3을 map으로 가공하게 됩니다.

Filtering Operators

필터링 연산자는 조건에 부합하는 값만 함수로 전달해줍니다. 말그대로 필터역할을 합니다.

대표적인 연산자로는 filter, take등이 있습니다.

filter는 x > 2라는 조건이 있다면 말그대로 x가 2를 넘는 값만 돌려줍니다.

take는 주어진 인수의 갯수만큼만 출력됩니다.

Combination Operators

콤비네이션 연산자는 Observable간의 연결처리를 수행할 수 있도록 해줍니다.

대표적인 연산자로 concat, merge등이 있습니다.

둘 다 생각하시고 많이 쓰셨던 그대로입니다.

Multicasting Operators

하나의 스트림을 여러 구독자에게 값을 보냅니다. 말그대로 다중출력 입니다.

대표적인 연산자로 multicast가 있습니다.

Error Handling Operators

오류가 발생했을때 처리하는 연산자입니다.

catch, retry가 있는데 catch는 오류가 발생한순간 받아서 주어진 처리를 진행하는 연산자입니다.

retry의 경우는 인수가 주어지는데 주어진 인수만큼 다시 반복하고 진행합니다.

이런식으로 작동합니다.

Utility Operators

각종 유틸기능을 담은 함수입니다.

delay, toArray, Timeout(주어진 시간이 지나면 out)등 여러가지 유틸리티 기능을 담고 있습니다.

Conditional and Boolean Operators

찾는 기능이나 조건에 관련된 연산자가 들어있습니다.

find, defaultIfEmpty, every등이 있습니다.

Mathematical and Aggregate Operators

숫자와 관련된 연산자입니다.

count, max, min, reduce가 있습니다.

스케줄러

스케줄러는 구독이 시작될 때와 알림이 올 때 제어하는 구성요소입니다. queue, asap(as soon as possible), async 세 가지의 유형이 존재하며 따로 제공하지 않으면 RxJS는 스스로 스케줄러를 선택합니다.

스케줄러는 세가지 특징을 갖고 있습니다.

  • 스케줄러는 데이터 구조로써 우선 순위, 다른 기준에 따라 작업을 저장하고 대기열에 넣는 방법을 갖고 있습니다.
  • 스케줄러는 작업이 실행되는 위치 또는 시점을 나타냅니다.
  • 스케줄러는 가상 시계를 가지고 있습니다. 그래서 해당 시간에만 나타나도록 할 수 있습니다.

스케줄러는 이러한 특징을 활용해 관찰자가 어떤 컨텍스트에서 Observer에게 통지를 전달할지 정의하고 있습니다.

Hot vs Cold Observables

관련 문서를 찾아서 보던 중 Hot vs Cold Observables를 모르면 언젠가 기술부채를 갚을 날이 올것이다 라는 말을 봤습니다.

그래서 한번 찾아봤는데 Cold Observable은 관찰자가 구독할때 까지 자원을 생성하지 않고 Hot Observable은 구독 여부에 상관없이 진행되다가 구독하면 그 때부터 볼 수 있도록 합니다.

뭔가 어려운데.. Cold는 시작버튼을 눌러야 진행한다고 보면 되고 Hot은 내가 구독하던말던 쭉 진행하다가 필요한 순간부터 받으면 될 것 같다.

어느 누구는 Cold는 영화관이고 Hot은 케이블 영화채널이라고 비유하기도 한다. 모르겠다…

그래서 결론은 왜 RxJS죠?