RxJS 빠르게 배우기 01 - Overview

RxJS 빠르게 배우기 01 - Overview

새로운 토이프로젝트를 하기 앞서, 프로젝트에 도입하기 위한 RxJS를 한 번 볼까 한다. RxJS를 사용하면 비동기 처리에 대해 정말 직관적이고 간단한 코드를 쓸 수 있다는 풍문을 들었기 때문에, 리액티브 프로그래밍에 대한 느낌도 잡아보고자…

이 시리즈는 주로 RxJS 공식 문서의 Overview 부분을 번역하면서, 참조로 ReactiveX에서 설명해주는 개념적인 부분을 공부한 내용이다. 모든 내용을 담지는 않았다.

Overview

Observable Sequences를 사용해 비동기와 이벤트 베이스의 프로그램을 함성하기 위한 라이브러리라고 RxJX 공식 문서에서는 설명하고 있다. Observable 이라고 하는 것은 RxJS의 핵심 타입이고 그 외 Observer, Schedulers, Subjects 라고 하는 타입들을 제공하고 있다.

RxJS에서 비동기 이벤트를 다루기 위한 기본적인 개념들은 다음과 같다.

  • Observable: 호출 가능한 미래 값들과 이벤트의 모임
  • Observer: Observable이 전달해주는 값을 어떻게 처리할지에 대한 콜백
  • Subscription: Observable의 수행, 기본적으로 실행의 취소에 유용함
  • Operators: map, filter, concat, reduce와 같은 연산으로 대상을 처리하는 함수형 프로그래밍 스타일을 가능하게 하는 순수 함수들
  • Subject: EventEmitter와 동일하다. 그리고 값이나 이벤트를 여러 옵저버들에게 동시 전달해주는 유일한 방법이다.
  • Schedulers: 중앙 집중된 동시성 컨트롤을 위한 dispatcher이다.

간단한 예시

1
2
// 일반적인 Event Listener 방식
document.addEventListener("click", () => console.log("Clicked"));
1
2
3
import { fromEvent } from "rxjs";

fromEvent(document, "click").subscribe(() => console.log("Clicked"));

순수성

RxJS를 강력하게 만드는 것은 값을 순수 함수들을 이용해서 만들어내는 것이다. 이게 뭔 뜻이냐면, 에러들에대한 취약점이 더 적다는 것을 의미한다.

1
2
3
// state를 지저분하게 할 수 있는 코드
let count = 0;
document.addEventListener('click', () => console.log(`${++count}` times));
1
2
3
4
5
6
7
// RxJS를 사용해서 state를 독립
import { fromEvent } from "rxjs";
import { scan } from "rxjs/operators";

fromEvent(document, "click")
.pipe(scan((count) => count + 1, 0))
.subscribe((count) => console.log(`Clicked ${count} times`));

scan 오퍼레이터는 배열에서 reduce와 유사하게 동작한다.

초기 값을 넣고, 다음 값이 어떤 처리를 거쳐야 하는지 콜백함수를 넣으면 되는 것 같음.

Flow

RxJS는 이벤트들의 흐름을 Obserbables를 통해서 컨트롤할 수 있게 도와주는 연산자들을 가지고 있는데, 아래 예시는 1초마다 클릭되도록 하는 코드를 비교한 것이다.

1
2
3
4
5
6
7
8
9
10
11
// 일반 자바스크립트
let count = 0;
let rate = 1000;
let lastClick = Date().now() - rate;

document.addEventListener("click", () => {
if (Date.now() - lastClick >= 1000) {
console.log(`Clicked ${++count} times`);
lastClick = Date.now();
}
});
1
2
3
4
5
6
7
8
9
10
11
// RxJS

import { fromEvent } from "rxjs";
import { throttleTime, scan } from "rxjs/operators";

fromEvent(document, "click")
.pipe(
throttleTime(1000),
scan((count) => count + 1, 0)
)
.subscribe((count) => console.log(`Clicked ${count} times`));

Values

값들을 Observables를 통해서 값들을 변형할 수 있다. 아래 코드는 현재 마우스의 x 축 값을 매 클릭마다 더하는 상황을 비교한 것이다.

1
2
3
4
5
6
7
8
9
10
11
let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;

document.addEventListener("click", (event) => {
if (Date.now() - lastClick >= rate) {
count += event.clientX;
console.log(count);
lastclick = Date.now();
}
});
1
2
3
4
5
6
7
8
import { fromEvent } from "rxjs";
import { throttleTime, map, scan } from "rxjs/operators";

fromEvent(document, "click").pipe(throttleTime(1000)),
map((event) => event.clientX),
scan((count, clientX) => count + clientX, 0).subscribe((count) =>
console.log(count)
);

그 외 값을 만들어내는 연산자들에는 pluck, pairwise, sample 등이 있다.

후기

함수형 프로그래밍을 잘 알지는 못 하지만 느낌이 난다고 해야 하나, 그렇다. Overview 단원 답게 얄팍했지만 예시 코드를 보면 꽤 괜찮아 보인다. 모르는 용어 사용에 직관적으로 익숙해질 필요가 있는 것 같다. 알고 있던 영어 단어와 실제로 사용되는 느낌에서 이질감을 느낀다.

Reference

댓글

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×