오늘 소개할 부분은
웹어플리케이션 개발시 발생할 수 있는 상태 전파 문제를 RxJS는 어떻게 접근했는지에 대한 이야기이다.


웹어플리케이션의 상태

우리가 만드는 웹어플리케이션은 하나의 큰 상태 머신이고 이를 구성하고 있는 크고 작은 단위들 또한 하나의 상태머신이다.
각각의 상태 머신들은 각자의 상태를 가지고 있고, 상태 머신들은 각자의 역할에 따라 서로 유기적으로 연결되어 있다.

A라는 작은 상태 머신의 상태값은 B의 입력값이 될수 있고, B의 상태값은 C와 D에 관련 있는 상태값 일수 있다.
따라서, A의 상태 값은 B로 전달되어야하고 B의 상태값은 다시 C와 D에 전달되어야만 한다.
이렇게 A의 상태 변화 정보가 B에 전달되어야하고 B의 상태값이 다시 C와 D에 전달되어야하는 이유는 바로 A, B, C, D 모듈간에 의존성이 있기 때문이다.

간단한 예를 들어보자.
사용자 정보(상태)를 System 클래스가 check() 함수에서 사용하고 있는 예제이다.
System과 User간에는 다음과 같은 의존성이 존재한다.

이렇게한 근본적인 이유는 데이터 흐름을 단순화함으로 복잡도를 낮추고 오류 발생 빈도를 줄이기 위해서 이다.
물론, 데이터가 양방향으로 흐르게 되면 사용상 편리할 수는 있다. 하지만, 어플리케이션의 규모가 커지게 되면 양방향으로 흐르는 데이터의 복잡도는 통제하기 어려울 정도로 복잡해진다.

이러한 이유로 최근 등장한 프레임워크들은 모두 단방향 데이터 흐름을 지향한다.

React와 Angular2+, Vue 모두 단방향 데이터 흐름을 지향한다.

Observable은 리액티브하다.

RxJS는 Observer 패턴과 마찬가지로 데이터가 발생하게되면 Observer에게 자동으로 그리고 빠르게 변경된 데이터를 전달한다.
이를 보고 리액티브하다고 이야기한다.
리액티브하다라는 의미를 이해하기 위해서는 우선 리액티브 프로그래밍(Reactive Programming)에 대한 정의 부터 살펴보자. 위키피디아에서는 다음과 같이 정의되어 있다.

리액티브 프로그래밍은 데이터 흐름과 상태 변화 전파에 중점을 둔 프로그램 패러다임이다. 사용되는 프로그래밍 언어에서 데이터 흐름을 쉽게 표현할 수 있어야하며 기본 실행 모델이 변경 사항을 데이터 흐름을 통해 자동으로 전파한다는 것을 의미한다.

출처 : https://en.wikipedia.org/wiki/Reactive_programming

위 정의에서 가장 핵심이 되는 단어는 데이터 흐름자동으로 전파이다. 즉, 상태 변화의 흐름이 자동으로 전파되는 것을 리액티브하다고 이야기한다.

리액티브의 가장 흔하게 드는 예로 ‘엑셀’을 이야기할 수 있다.

A열의 값과 B열의 값의 합을 나타내는 C열은 A열이나 B열의 값이 변화되는 경우 자동으로 C열의 값이 변경된다.
이렇게 A나 B열의 변경사항이 데이터 흐름을 통해 자동으로 C열에 전파되도록 구조화하는 프로그래밍의 패러다임을 리액티브 프로그래밍이라고 한다.

이 말은 앞에서 살펴 보았던 상태 변화에 대한 우리의 고민들과 일맥 상통한다고 이야기할 수 있다.
이런 고민의 해결책이 Observer 패턴이고, RxJS는 이런 Observer 패턴을 개선하여 어플리케이션에서 발생하는 모든 데이터를 리액티브하게 전달 할 수 있게 해준다. 따라서, RxJS는 리액티브 프로그래밍(Reactive Programming)을 지향하는 라이브러리이다.

정리

이 장에서는 웹어플리케이션의 상태가 어떻게 전파되는지를 살펴 봄으로써 상태 전파로 인해 발생할 수 있는 문제점을 살펴보았다. 또한, 이러한 문제를 효과적으로 해결했던 Observer 패턴에 대해서도 살펴보았다.
Observer 패턴은 느슨하게 연결되어 Subject와 Observer간의 의존도를 줄였으며, Push 방식으로 데이터를 전파함으로써 상태 전파에 대한 많은 문제를 해결했다.
RxJS에서는 이런 Observer 패턴을 개선하여 상태 전파 문제를 해결하려고 하였다.
에러상황과 종료상황에 대한 인터페이스를 확장하였고, 데이터를 단방향으로 흐를 수 있도록 개선함으로써 코드의 복잡도를 낮추었다. 이런 결과 RxJS는 궁극적으로 Reactive Programming을 지향하는 라이브러리가 되었다.

다음장에서는 RxJS가 고민한 로직 오류에 대해 살펴보기로 하자.

Comment and share

Reactive Programming

이 글은 기존에 잘 정리된 문서를 보고 학습한 결과를 바탕으로 제 기준으로 다시 간단히 정리한 문서입니다.

Reactive Programming 이란?

참조 문서

https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

Reactive Programming

Reactive programming is programming with asynchronous data streams.
You can listen to that stream and react accordingly.

  • Reactive Programing은 기본적으로 모든 것을 스트림(stream)으로 본다. 이벤트, ajax call, 등 모든 데이터의 흐름을 시간순서에 의해 전달되어지는 스트림으로 처리한다. 즉, 스트림이란, 시간순서에 의해 전달되어진 값들의 collection 정도로 이해해 보자.
  • 각각의 스트림은 새로 만들어(branch)져서 새로운 스트림이 될 수도 있고, 여러개의 스트림이 합쳐(merge) 질수 도 있다.
  • 스트림은 map, filter과 같은 함수형 메소드를 이용하여, immutable하게 처리할 수 있다.
  • 스트림을 listening 함으로써 데이터의 결과값을 얻는다. 이를 subscribe라고 표현한다.

Observable과 Observer

An observer subscribes to an Observable. An Observable emits items or sends notifications to its observers by calling the observers’ methods.
http://reactivex.io/documentation/observable.html

  • Observable은 observer의 메소드를 호출하면서 item이나 정보등을 호출(emit)하는 역할을 한다. Observer는 onNext, onError, onCompleted의 메소드가 구현되어 있다.
  • Observer는 observable을 subscribe한다. Observer는 Subscriber, watcher, reactor로 불려진다.

그럼 왜 Reactive Programming 인가?

Apps nowadays have an abundancy of real-time events of every kind that enable a highly interactive experience to the user. We need tools for properly dealing with that, and Reactive Programming is an answer.

  • 함수형으로 만들기 때문에, 하나의 함수는 그 역할 자체에 집중할수 있다.
  • Promise의 장점을 극대화할 수 있다.
    Reactive Programming에서 갑자기 Promise를 이야기하는 이유는, RxJS의 Observable이 Promise와 개념적으로 유사하다. 차이가 있다면, Promise는 단 하나의 value를 다룰 수 있지만, Observable은 다수의 value를 다룰 수 있다.

    1
    2
    myObservable.subscribe(successFn, errorFn);
    myPromise.then(successFn, errorFn);

    The Promise is an Observable
    The Observable is not a Promise
    ES7 스펙에 Observable이 제안되어 있지만 현재는 표준이 아니다. 하지만, Promise는 Promises/A+ 표준이다.

    처음 Promise를 접할 때에는 좀 낯설었지만, 실제 구현상의 편리함이나, 로직의 심플함, 비동기 처리를 동기식으로 개발할 수 있는 장점 덕분에, 좀더 알아먹기 쉬운 코딩을 할수 있다. 익숙해지면, Observable은 Promise보다 더 강력하다.

  • Observable은 A steam에 의해 B stream이 영향을 받는 경우, A만 바꿔도 B가 자동으로 바꿀 수 있도록 구성할 수 있어서, 데이터의 동기화를 간편하게 할 수 있다. 이러한 이유는 A와 B stream 사이의 관계를 선언적으로 선언했기 때문에 가능하다. [예제]

RxJS 참조 문서

ReactiveX 공식

http://reactivex.io/

stream 생성 static 메소드

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/which-static.md

stream operator

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/which-instance.md

observable api

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md

operator 다이얼그램

http://rxmarbles.com/

실습한 예제

실습하면서 공부한 예제
http://jsbin.com/pekemu/edit?js,console,output

생각해볼 문제

  • map, filter와 같은 함수를 계속 쓰면, 객체를 계속 만드는 거 아닌가?

    RxJS는 객체를 재활용함. 문제없음. 음하하하

    RxJS and Reactive Programming - Modern Web UI - May 2015 from Ben Lesh

  • RxJS와 Reactive Programing은 같은 건가?

    아니, RxJS는 Reactive Programming에서 시간을 제어할 수 있는 Schedule 기능, 등이 포함되어 있는 라이브러리이다.

Comment and share

  • page 1 of 1
Author's picture

sculove

아내와 아들 그리고 딸밖에 모르는 남편


FrontEnd Developer


대한민국/서울