오르카의 아틀리에

비단 UniRx 뿐만 아니라 Rx로 프로그래밍을 하다 보면, 필연적으로 여러 개의 Observable을 동시에 구독하는 것처럼 동작하게 만들어야 할 필요가 있습니다.

 

예를 들어 비밀번호 확인을 위해 2개의 input필드가 있고, 그 값이 바뀔 때마다 비밀번호가 유효한 규칙으로 작성되었는지 확인하고 싶을 때를 생각해봅시다. 2개의 input 필드를 각각 구독하고 유효한 규칙인지 판단해도 되지만, 2개의 input Observable을 합성하고 그것을 구독하는 방법도 있을 것입니다. 이런 상황처럼 실제로 UniRx를 이용하여 게임 로직을 작성하다 보면, 여러 개의 ReactiveProperty나 Subject를 동시에 구독해서 처리해야 하는 상황들이 많이 나오게 됩니다.

 

0. Zip

말 그대로 2개의 스트림을 하나로 압축합니다. 그림으로 설명하면 다음과 같습니다.

Zip의 동작

보이는 것처럼 타겟 Observable에 흘러온 데이터를 1:1로 대응해서 흘리는 Observable을 만듭니다. C, D 데이터가 들어오는 것을 보면 어느 한쪽에 쌍을 이룰 데이터가 들어오지 않으면 해당 다른 쪽 데이터를 보관하는 것을 알 수 있습니다. 거기에 한번 흘려진 데이터는 버려집니다.

 

1. ZipLatest

이름을 통해 쉽게 예측할 수 있을 것 같습니다. Zip이긴 한데 Latest한 데이터를 이용하는 친구겠죠. 그림으로 표현하면 다음과 같습니다.

ZipLatest의 동작

그냥 Zip과는 다르게 3D라는 데이터가 흐른 뒤 더 이상 데이터가 흐르지 않고 있습니다. 두 번째 Observable에 최신 데이터가 남아있지 않기 때문이죠. 또한, 두 번째 Observable에 흐른 C라는 데이터는 맞는 짝을 찾지 못하고 소멸했습니다.

 

2. CombineLatest

이 친구는 Zip과는 다르게 한번 합성해서 흘려보낸 데이터를 버리지 않는다는 특징이 있습니다. 그림으로 표현하면 다음과 같습니다.

CombineLatest의 동작

연결된 두 개의 스트림 중 어느 한 곳에서 데이터가 흐르면 합성된 Observable에도 데이터가 흐르며, 데이터의 내용은 각 스트림에 흐른 최신 데이터가 이용됩니다. 현제 프로젝트에서 ZipLatest와 더불어 가장 많이 사용하고 있는 스트림입니다. 하나의 뷰를 여러 모델이 참조돼서 업데이트되어야 할 때 주로 사용하고 있습니다.

 

3. Merge

말 그대로 Observable을 합쳐줍니다. 그림으로 확인하면 다음과 같습니다.

Merge의 동작

 

아무 처리 없이 N개의 스트림에 흐르는 데이터를 전부 하나의 Observable로 흐르게 해 주는 것이기 때문에 모든 스트림의 타입이 같아야 합니다. 여러 개의 Button이 한 가지 동작을 한다고 했을 때 정도에 사용할 수 있을 것 같습니다.

 

4. Concat

Array에서 Concat을 사용해보신 분이라면 익숙할 것입니다. 하나의 스트림이 끝나면 뒤에 추가한 스트림이 흐르기 시작합니다. 그림으로 보도록 하죠.

Concat의 동작

첫 Observable이 완료될 때까지 그 데이터를 전달하고 OnComplete되면 두 번째 Observable의 데이터를 흘리기 시작합니다. 모든 Observable이 OnComplete 되면 종료됩니다. 현제 프로젝트에서는 잘 사용하지 않았지만 네트워크가 붙으면 사용할 수 있을 것 같습니다.

 

5. WithLatestFrom

언듯 보면 CombineLatest와 같아 보이지만, 특징이 한 가지 있습니다. 그림을 보면서 살펴보도록 합시다.

WithLatestFrom의 동작

CombineLatest는 합성된 Observable에 데이터가 흐르는 순간이 타겟이 되는 Observable 중 어디든 데이터가 흐르는 순간이었지만, WithLatestFrom은 첫 번째 Observable에 데이터가 흐르는 순간입니다. 만약 Latest한 데이터가 없다면 데이터는 흐르지 않습니다.

 

6. Amb

Amb는 N개의 Observable 중 가장 먼저 데이터가 흐른 Observable을 반환합니다. 그림을 보도록 하죠.

Amb의 동작

그림처럼 가장 먼저 A라는 데이터가 세 번째 Observable에 다른 Observable보다 먼저 흘렀으므로 Amb의 합성 Observable에는 세 번째에 흐르는 데이터만 흐르게 됩니다.