ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxSwift - merge()에 대해서 알아보자.
    Ray Wenderlich/RxSwift 2018. 7. 6. 02:23


    Ch9. Combining Operators p.184 - p.186


    merge()

    RxSwift에서 시퀀스를 합쳐주는 operator는 다양하다. 

    그 중, merge를 이용해 쉽게 접근해보자.


    아래 그림을 보고, merge가 어떤 역할을 하는지 한번 짐작해보자.


    어떤 역할을 하는지, 코드를 통해서 알아보자. (아래는 이미지입니다. 텍스트로 작성한 코드는 본문 최하단에 첨부)

    1. PublishSubject를 두 개 만들었다.

    2. Observable의 Observable을 만든다. source의 타입은 Observsble<Observable<String>>이다.

    3. merge()를 사용했다. merge()의 리턴 값을 subscribe하고 있다.

    4. leftValues에는 독일의 도시가, rightValues에는 스페인의 도시가 들어있다.

        leftValues와 rightValues는 각각 left와 right에 next이벤트로 전달된다.

        하지만 랜덤으로 전달되고 있기 때문에, 어떤 순서로 전달되는지 우리도 알 수 없다.

    5. dispose()를 호출하여 메모리에서 해제시켜준다.


    수행결과는 아래와 같다. (순서가 랜덤이기 때문에 항상 다른결과가 나온다.)

    Left: Berlin 

    Left: Munich 

    Right: Madrid 

    Right: Barcelona 

    Right: Valencia 

    Left: Frankfurt


    merge는 merge하고 있는 여러 시퀀스들을 동시에 subscribe하면서, 먼저 오는 이벤트들을 바로 전달시켜준다. 

    무조건 선착순이다.


    또한 merge()와 관련된 몇 가지 규칙이 있다.

     • merge() completes after its source sequence completes and all inner sequences have completed.(내부 시퀀스가 종료되면 merge시퀀스도 종료됨)

     • The order in which the inner sequences complete is irrelevant. (내부 시퀀스가 complete되는 시점은 모두 독립적)

     • If any of the sequences emit an error, the merge() observable immediately relays the error, then terminates.(만약 내부시퀀스에서 에러가 발생하면 그 즉시 merge시퀀스도 에러를 발생시키며 종료됨)


    예제에서는 두 개의 시퀀스만 합쳤지만, 두 개 이상의 시퀀스를 합칠 수 있다!!

    그리고, 최대 몇 개의 시퀀스를 합칠 것인지 정할 수도 있다.


    merge(maxConcurrent:)메소드가 바로 그 역할을 한다.

    merge(maxConcurrent:)를 사용하여 시퀀스를 합치면, 일단 maxConcurrent개수 만큼 시퀀스를 합친다.

    만약 maxConcurrent가 작아서 합쳐지지 못한 시퀀스는 큐에 대기하다가, 내부 시퀀스 중 하나가 complete하면 합쳐진다.





    별첨.

    <본문 사용 코드>

        // 1

        let left = PublishSubject<String>()

        let right = PublishSubject<String>()

        

        // 2

        let source = Observable.of(left.asObservable(), right.asObservable())

        

        // 3

        let observable = source.merge()

        let disposable = observable.subscribe(onNext: { value in

            print(value)

        })

        

        // 4

        var leftValues = ["Berlin", "Munich", "Frankfurt"]

        var rightValues = ["Madrid", "Barcelona", "Valencia"]

        repeat {

            if arc4random_uniform(2) == 0 {

                if !leftValues.isEmpty {

                    left.onNext("Left:  " + leftValues.removeFirst())

                }

            } else if !rightValues.isEmpty {

                right.onNext("Right: " + rightValues.removeFirst())

            }

        } while !leftValues.isEmpty || !rightValues.isEmpty

        

        // 5

        disposable.dispose()


Designed by Tistory.