성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

RxJS

RxJS 기초 - 스트림(Stream)

제이콥(JACOB) 2020. 2. 1. 18:49

 RxJS는 파일 읽기, HTTP 호출, 키 입력 또는 마우스 움직임 등의 이벤트 데이터 소스를 처리하는 단일 프로그래밍을 사용하여 콜백 또는 Promise 기반 라이브러리를 정확히 같은 방식으로 대체한다. 그리고 RxJS를 사용하면 시간 경과에 따라 분리된 대용량 데이터를 보다 간결하고 선언적으로 처리할 수 있다.

 파이프라인은 데이터를 사용할 수 있을 대 순서대로 실행되는 일련의 로직 영역(비즈니스 로직 영역)이다.

그리고 왼쪽에 있는 은 이벤트 생성자이며, 애플리케이션에서 소비될 다양한 형태의 데이터를 생산하는 데이터 소스가 있는 곳이다. 소바자는 받은 데이터로 무엇인가를 하거나 이벤트들을 구독하는 개체이다. 마지막으로 파이프라인에 스트림을 변환한다고 써있는데, 스트림은 시간에 따라 발생하는 일련의 이벤트라고 생각하면 된다. 

 

지금은 이게 뭔지 이해를 못해도 된다. 곧 화면을 올려서 다시 보고 이해할 수 있을 것이다.

Everything is stream

"모든 것이 스트림이다"라는 말은 한번쯤은 들어봤을 것이다. 스트림의 개념은 HTTP에서 받은 바이트 데이터부터 단일 정수에 이르기까지 모든 값을 가진 데이터 요소에 적용될 수 있다. 스트림은 스트림을 듣는 구독자(또는 옵저버)가 있을 때까지 실제로 아무 일도 하지 않고 유휴 상태로 있다. 생성되면 바로 일을 시작하는 Promise와는 다르다. RxJS는 변화의 전파로 스트림의 데이터를 보고 이해해야 하는 패러다임의 전환이다.

 

Stream이라는 추상 데이터 타입이 있다고 하고 예를 들어보자.

Stream(1); // 아무 일도 없다.

Stream(1).subscribe(value => {
    console.log(value); // 1 구독자가 값을 받으면 스트림이 완료된다.
});

위 예제에서 스트림은 숫자로로 확장할 수 있으며, 배열로도 확장할 수 있다. 

Stream([1, 2, 3, 4, 5])
    .filter(num => num % 2 === 0)
    .map(num => num * num)
    .subscribe(value => {
        console.log(value); // 4 16
    });

 그리고 맨 처음에 언급된 그림에 위에 로직을 대입해 보자. 그럼 이제 조금씩 이해가 되기 시작할 것이다.

생성자는 이벤트를 단순히 선형적으로 내보내며, 이러한 이벤트는 파이프라인을 통해 제출되고 변환되며, 최종데이터는 모든 구독자에게 보내져 소비된다.


시간 개념의 추상화

 비동기 코드에서 가장 어려운 부분은 지연 시간과 대기 시간을 처리하는 것이다. RxJS는 시간이 지남에 따라 소스에 상관없이 같은 프로그래밍 모델로 추상화되있다. 그리고 RxJS는 연속적인 이벤트 시퀀스의 개념을 제시했다. 코드가 완전히 선형이고 동기인 것처럼 데이터를 변환할 수 있는 것이며 마우스 이벤트 같은 이벤트를 숫자 배열 처리하듯이 쉽게 처리할 수 있도록 했다. 

 


이제 위에서 나온 개념들을 조금 더 정의해 보자.

  • 생산자: 생산자는 데이터 소스이다. 스트림에는 항상 데이터 생산자가 있어야 하며, RxJS에서 수행할 모든 로직의 시작점이 된다. 이러한 생성자를 옵저버 패턴에서는 서브젝트(Subject)라고 정의하며, RxJS에서는 옵저버블(Observable)이라고 부른다.
  • 소비자: 소비자가 소비할 이벤트에 대해 생산자(Observable)을 듣기(subscribe) 시작하면 스트림이 생기게 되고, 이 시점에 스트림은 이벤트를 푸시하기 시작한다. 그리고 소비자를 옵저버(Observer)라고 부른다.
  • 스트림: 스트림은 생산자에서 소비자로만 이동하며 다른 방향으로는 이동하지 않는다. 사용자가 키보드의 키를 누르면 다른 프로세스에서 소비되려고 흘러가는 이벤트를 생산하게 된다. RxJS와 관련하여 스트림은 항상 업스트림 옵저버블에서 다운스트림 옵저버로 흐른다. 그리고 이 두 컴포넌트는 느슨하게 결합되어 있으며, 애플리케이션의 모듈성을 향상 시킨다. 스트림은 소바자와 생산자만 요구하며, 소비자가 생산자에서 이벤트를 받기 시작하면 스트림을 생성할 수 있다. 
  • 파이프라인: 생산자에서 소비자로 전달되는 데이터를 조작하거나 편집한다. 이는 메서드 목록(observable operators)이 실행되는 곳이기도 하다. 경로(en route)에서 데이터 조작은 소비자의 기대치에 맞게 생산자의 결과물을 조정할 수 있으며, 두 개체 간 관심사의 분리(separation of concerns)가 촉진되고 모듈성에도 큰 도움이 된다. 
  • 시간: 이 모든 것을 뒷받침하는 암묵적 요소이다. RxJS에는 항상 시간의 기본 개념이 있어 스트림을 조작하는데 사용할 수 있다. 

Stream은 설명하기 위해 만들었기 때문에 빨간줄이... ㅠ

 

 

반응형