Combine) Combining Operators

Havi·2022년 3월 8일
0

Combine

목록 보기
7/8

prepend(Output...)

... syntax를 input으로 받고 있기 때문에 원하는 숫자의 Output Type Value를 Prepend할 수 있다.

let publisher = [3, 4].publisher
publisher
  .prepend(1, 2)
  .sink(receiveValue: { print($0) })
  .store(in: &subscriptions)
/*prints
1
2
3
4
*/

prepend(Sequence)

마찬가지로 sequence 또한 prepend 할 수 있다.

let publisher = [5, 6, 7].publisher
publisher
  .prepend([3, 4])
  .prepend(Set(1...2))
  .sink(receiveValue: { print($0) })
  .store(in: &subscriptions)
/*prints
1
2
3
4
5
6
7
*/

prepend(Publisher)

publisher 또한 prepend 할 수 있다.
prepend되는 publisher의 completion이 불린 뒤에 emit된 value만 print된다.

let publisher1 = [3, 4].publisher
let publisher2 = [1, 2].publisher
publisher1
  .prepend(publisher2)
  .sink(receiveValue: { print($0) })
  .store(in: &subscriptions)
/*prints
1
2
3
4
*/

let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<Int, Never>()

publisher1
    .prepend(publisher2)
    .sink(receiveValue: { print($0) })
    .store(in: &subscriptions)

publisher1.send(10) // 안불림

publisher2.send(1)
publisher2.send(2)
publisher2.send(3)
publisher2.send(4)

publisher1.send(11) // 안불림

publisher2.send(completion: .finished)

publisher1.send(12)
publisher1.send(13)
publisher1.send(completion: .finished)
/*prints
1
2
3
4
12
13
*/

append(Output...)

append도 prepend와 마찬가지다.

let publisher = [1].publisher
publisher
    .append(2, 3)
    .append(4)
    .sink(receiveValue: { print($0) })
    .store(in: &subscriptions)
/*prints
1
2
3
4
*/

append(Sequence)

append(Publisher)

위 두 Operator는 Prepend와 같은 방식으로 동작하므로 생략한다.

switchToLatest

RxSwift의 flatMapLatest와 마찬가지로 이후 가장 마지막 event를 받으며 동시에 방출 될 경우 이전 event를 cancel시킨다.

let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<Int, Never>()
let publisher3 = PassthroughSubject<Int, Never>()

let publishers = PassthroughSubject<PassthroughSubject<Int, Never>, Never>()

publishers
    .switchToLatest()
    .sink(
        receiveCompletion: { _ in print("Completed!") },
        receiveValue: { print($0) }
    )
    .store(in: &subscriptions)

publishers.send(publisher1)
publisher1.send(1)
publisher1.send(2)

publishers.send(publisher2)
publisher1.send(3)
publisher2.send(4)
publisher2.send(5)

publishers.send(publisher3)
publisher2.send(6)
publisher3.send(7)
publisher3.send(8)
publisher3.send(9)

publisher3.send(completion: .finished)
publishers.send(completion: .finished)
/*prints
1
2
4
5
7
8
9
Completed!
*/

switchToLatest가 유용한 상황은 다음과 같다. Network Request가 실행되는 Button이 있다고 했을 때, User가 이 버튼을 여러 번 누른다고 가정하자. 그렇다면 pending request가 아닌 latest request를 쓰는 것이 합당하다.

merge(with:)

merge는 두 개의 publisher에서 어떤 publisher건 상관 없이 온 순서대로 방출한다.


let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<Int, Never>()
publisher1
    .merge(with: publisher2)
    .sink(
        receiveCompletion: { _ in print("Completed") },
        receiveValue: { print($0) }
    )
    .store(in: &subscriptions)
publisher1.send(1)
publisher1.send(2)
publisher2.send(3)
publisher1.send(4)
publisher2.send(5)
publisher1.send(completion: .finished)
publisher2.send(completion: .finished)
/*prints
 1
 2
 3
 4
 5 
 Completed
 */

combineLatest

얘도 RxSwift의 combineLatest와 마찬가지로 .. 두 퍼블리셔에서 가장 최근에 온 값들을 조합해 방출한다.

let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<String, Never>()
publisher1
    .combineLatest(publisher2)
    .sink(
        receiveCompletion: { _ in print("Completed") },
        receiveValue: { print("P1: \($0), P2: \($1)") }
    )
    .store(in: &subscriptions)
publisher1.send(1)
publisher1.send(2)
publisher2.send("a")
publisher2.send("b")
publisher1.send(3)
publisher2.send("c")
publisher1.send(completion: .finished)
publisher2.send(completion: .finished)
/*prints
 P1: 2, P2: a
 P1: 2, P2: b
 P1: 3, P2: b
 P1: 3, P2: c
 Completed
 */

zip

zip도 RxSwift와 마찬가지로 두 퍼블리셔에서 온 순서대로 조합해 방출한다.

let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<String, Never>()
publisher1
    .zip(publisher2)
    .sink(
        receiveCompletion: { _ in print("Completed") },
        receiveValue: { print("P1: \($0), P2: \($1)") }
    )
    .store(in: &subscriptions)
publisher1.send(1)
publisher1.send(2)
publisher2.send("a")
publisher2.send("b")
publisher1.send(3)
publisher2.send("c")
publisher2.send("d")
publisher1.send(completion: .finished)
publisher2.send(completion: .finished)
/*prints
 P1: 1, P2: a
 P1: 2, P2: b
 P1: 3, P2: c
 Completed
 */
profile
iOS Developer

0개의 댓글