Reactive X가 뭐야?

Tabber·2021년 8월 24일
1

Reactive Extension

목록 보기
1/4
post-thumbnail

이 글은 공식문서에 소개된 글을 기준으로 제 나름대로의 의견이 합쳐진 글입니다!
공부를 하면서 쓰는 글이라 정확하지 않을 수 있습니다 😭

iOS 개발 공부를 하면서 자연스레 회사들의 iOS 개발자를 뽑는 기준에 대해 찾아본적이 있었다.
그런데 하나같이 다들 'RxSwift', 'combine' 등을 사용 할 줄 아는 사람을 원하는 것 같았다.

그래서 이번 기회에 이게 뭔지, 왜 현업에서 많이 사용하는지를 알아보려고 한다

Reactive X 가 뭐야?

일단 RxSwift에서 이름의 제일 앞에 위치한 Rx 가 뭔지 알아보자.

일단 Rx는 Reactive X 의 준말이다. 근데 한 번 더 이 이름을 파헤쳐보면 ,

정확한 이름은 Reactive Extensions 이다.

Reactive X 의 공식 깃허브 Organizations 를 보면, Reactive Extensions for Async Programming 이라는 설명이 나와있다.

Async Programming 을 위한 Reactive Extensions 이라는 말이다.

비동기 프로그래밍을 위한 반응형 익스텐션 이라는데, 그럼 비동기 프로그램에서 사용하는 라이브러리 같은 개념인듯 하다.

Async Programming 은 또 뭐야?

일단 한국말로 번역을 해보자면 , 비동기 프로그래밍이라는 소리다.
그럼 비동기는 뭘 의미하는 걸까?

일단 비동기가 있으면 동기도 있을테다. 이 둘의 차이를 보며 비동기의 뜻을 알아보자.

동기 프로그래밍

위 사진처럼 작업 테이블에 작업이 3개가 존재한다고 하자.

동기 프로그래밍의 핵심은 순서대로 작업하나가 다 끝나야 다음 작업으로 넘어갈 수 있다.

작업의 시작과 끝을 한번에 다 봐야한다라는 것이다.

만약 작업 1이 10초 이상을 할애하는 작업이라고 치면, 프로그램은 저 10초를 다 기다려야 다음 작업으로 넘어갈 수가 있는 것이다.

이게 안좋은 점이 뭐냐면, 만일 앱에 용량이 큰 영상을 다운받아야 하는 상황이라고 친다면, 영상을 다 다운받기 전까지는 앱이 중단되어 있는 모습이 연출될 수 있다라는 것이다. 따라서 동기 프로그래밍은 여러 작업을 빠르게 처리 해야하는 시스템에서는 좋지 않은 모델이다.

비동기 프로그래밍

이렇게 한 작업 테이블에서, 작업을 하나 시작했다고 하더라도, 테이블 자체는 일단 이어나간다.

그리고 이어나가면서 작업이 있다면 일단 시작하는 것이다.

그러다가 작업이 끝나는 순서대로 작업 종료의 리턴값을 반환해주는 것이다.

이렇게 된다면 아까 앱 얘기로 다시 설명을 해보자. 앱이 시작되고, 용량이 큰 영상을 다운받기를 시작한다. 그리고 다운을 받든말든 앱은 계속 돌아간다. 그러다, 다운이 끝났다면, 그 때 앱 UI에 영상을 띄워주는 방식인 것이다.

자, 이제 비동기 프로그래밍에 대해 조금은 알아낸듯 하다.

다시 본론으로 돌아와서.

이제 Reactive X에 대해 알아보자!

ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.

ReactiveX는 관찰이 가능한(observable) 시퀀스(사건이나 작업인듯)를 사용하여 비동기식 및 이벤트를 기반으로 한 프로그램 구성을 위한 라이브러리이다.

그렇다. Extension 자체가 확장이라는 의미를 가지고 있듯, Reactive X는 라이브러리이다.

이 라이브러리는 비동기 프로그래밍을 더 쉽고, 직관적으로 행하기 위해 만들어진 라이브러리라는 말이다!

그럼 관찰이 가능한(observable)것은 어떻게 동작하길래 이렇게 비동기적인 시스템을 구축할 수 있을까?

Observable

Reactive X 에서 Observer는 Observable을 구독한다.(구독이 감시와 같은 개념)

구독을 통해서 해당 Observable이 값이 바뀐다면 이를 Observer가 알아채야 하기 때문이다.

그리고 이 패턴(Observer Pattern)은 Observable이 리턴값(completed나, Event)을 보낼 때까지 기다리는 동안 프로그램이 Block 될 필요가 없기 때문에, 동시 작업(비동기적) 을 쉽게 수행할 수가 있다.

대신, Observable이 나중에 Completed와 같은 이벤트를 수행할 때마다 적절하게 반응할 준비가 되어있는 Observer 형태의 감시요소를 만든다.(인터페이스와 같은 개념인듯)

위 사진은 Marble Diagram 이다. 이 Diagram은 Observable변환된 Observable 표시한 Diagram이다.

그러니까 위 다이어그램은 하나의 Observable의 상황을 예시로 든 것 이다.

위는 Observable, 아래는 Observer입장에서 발행된 데이터의 연속이다.

아까 Observer가 Observable을 구독하고 있다고 했다. 그래서 구독한 Observable에서 발행된 데이터들을 Observer가 어떻게 받아내는지, 그 발행된 데이터는 어떻게 변환이 되어 나오는지를 볼 수 있는 다이어그램인 것이다.

공식문서에 설명하는 구동방법(Background)

우리가 보는 대부분의 소프트웨어 프로그래밍 작업에서는 작성하는 코드들이 한번에 하나씩 실행되어 작성하는 순서대로(절차지향) 완료될 것으로 예상한다.

하지만 Reactive X에서는 많은 명령들이 병렬로 실행될 수 있으며, 나중에 Observers를 통해 임의 순서대로 결과를 가져올 수 있다.

메서드를 호출하는 대신, Observable의 형태로, 데이터를 변환하는 메커니즘을 정의한 다음 Observer가 Observable을 구독하게 된다. 이 때, 이전에 정의된 메커니즘이 실행되어 Observer가 변환되어 나오는 데이터들을 알아채 그 데이터들을 가져오고 응답하게 된다.

이러한 접근 방식의 장점은 서로서로에게 의존하지 않는 독단적인 작업이 있을 경우 각 작업이 다음 작업을 시작하기 전에 완료될 까지 기다릴 필요 없이 모든 작업을 동시에 시작할 수 있다라는 것 이다.
이렇게 하면 전체 작업 목록 중, 가장 긴 작업을 프로그램을 중단시키지 않고 완료할 수 있다.

이러한 비동기 프로그래밍과 Observer Design Pattern을 설명하는데는 많은 용어들이 필요하다.

대표적으로 위에서 사용한 Observer와 Observable.

그리고 Observer를 다른 용어로도 사용이 가능한데,
"subscriber", "watcher" 아니면 "reactor" 라고도 불린다. (이런 용어들이 나와도 헷갈리지 말자)

Observer 설정하기(만들기)

Observer는 일반적인 메서드와는 약간 다르다.

일반적인 메서드

일반적인 메서드 호출(Reactive X에서 일반적인 비동기 병렬 호출과 같음)에서 흐름은 다음과 같다.

  1. 메서드를 호출한다.
  2. 해당 메서드의 반환값을 변수에 리턴한다.
  3. 변수를 가지고 새로운 Value를 사용하며 유용한 작업들을 수행한다.
func someMethod(_ itsParameters: Int) -> Int {
	return itsParameters * 2
}

let itsParameters = 2

returnVal = someMethod(itsParameters)
// returnVal = 4

이런 느낌인 것이다.

비동기적 모델

비동기 모델에서의 흐름은 다음과 같다.

  1. 비동기 호출에서 반환 값을 유용한 작업을 수행하는 메서드를 정의한다.
    [ 이 메서드는 Observer의 일부이다.]
  2. 비동기 호출 자체를 Observable로 정의한다.
  3. Observer를 Observable에 구독시킨다.(동시에 Observable의 초기화, 작업이 시작된다.)
  4. 계속 작업을 수행한다.
  5. Emitter 인터페이스를 통해 return Call이 나올 때마다, Obsever의 메서드가 Observable의 반환 Value에 대해 작동하기 시작한다.
// Observer 핸들러를 정의하지만, 호출은 하지 않는다.
// (in this example, the observer is very simple and has only an onNext handler)
def myOnNext = { it -> do something useful with it }
// Observable을 정의하지만, 호출하지는 않는다.
def myObservable = someObservable(itsParameters)
// Observer(subscriber)를 Observable에 구독하게 하고, Observable을 호출한다.
myObservable.subscribe(myOnNext)
// 계속 작업을 이어나간다.

일반적인 메서드 호출과는 다르게, 일단 계속 작업이 이어지는 상황에서 작업에 대한 진행은 Observable에서 진행하고, Observer가 그 작업을 감시하고 있는 상태이다.

그 때, Observable진행한 작업이 Emitter 인터페이스를 통해 Completed나 Event와 같은 return Call이 나올 때마다, Observer은 반환된 값에 따라 반응만 하면 되는 구조이다.

onNext, onCompleted, and onError

인터페이스를 통해 알려줄 수 있는 상태들은 위 처럼 3가지가 존재 한다. 하나씩 알아보자.

onNext

Observable에서 item들을 내보낼 때마다 이 메서드를 호출한다.
그러니까, 아얘 완료된 상태는 아니고 데이터가 하나씩 발행됐을 때마다 이 메서드가 호출되는 것이다.

onCompleted

Observable에서 오류가 발생하지 않고, 마지막으로 Next가 호출된 후 이 메서드를 호출하게된다.

onError

Observable에서 예상한 데이터를 생성하지 못했거나, 다른 오류가 발생했을 경우에 호출되는 메서드이다.

이 메서드가 호출된 다음 부터는 Next또는 Completed가 호출되지 않는다. onError 메서드는 매개변수로 오류의 원인이 무엇인지를 나타내준다.

Observable의 조건에 따라, onNext는 (인덱스와 비슷한 개념인듯)0부터 호출 할 수 있다.
항상 onCompleted 혹은 onError 둘 중 하나로만 데이터 발행이 종료되어야 한다.

오늘은 이렇게 Reactive X에 대해 간단히 알아보았다.

다음글은 RxSwift에 대해 알아보겠다.

아직 모르는게 너무 많다. 더 열심히 공부해보자.

profile
iOS 정복중인 Tabber 입니다.

0개의 댓글