Resource를 관리할 수 있는 2가지 연산자가 있습니다.
- share
- multicast
share
upstream에서 받은 요소를 여러 subscibers에게 공유하는 Publisher.Share 클래스의 인스턴스입니다.
연산자는 반환한 publisher는 여러 subscribers를 지원합니다.
subscribers는 publisher로부터 변경되지 않은 요소와 완료 상태를 받습니다.
Publisher.Share는 사실상 Publishers.Multicast 와 PassthroughSubject의 조합으로 암시적으로 autoconnect이 포함되어 있습니다. 처음 들어오는 subscriber와 함께 한 번 구독합니다. upstream에서 받은 값을 첫 subscriber 및 이후 구독하는 subscribers에게 전달합니다.
share 연산자를 사용하여 두 명의 subscriber에게 각각 동일한 난수를 공유합니다.
연산자가 없으면 서로 다른 임의의 값을 수신합니다.
let pub = (1...3).publisher
.delay(for: 1, scheduler: DispatchQueue.main)
.map( { _ in return Int.random(in: 0...100) } )
.print("Random")
.share()
cancellable1 = pub
.sink { print ("Stream 1 received: \($0)")}
cancellable2 = pub
.sink { print ("Stream 2 received: \($0)")}
구독이 생성되었을 때, 이미 데이터 전송이 완료될 수 있습니다.
multicast
downstream subscribers가 여러 명이지만 upstream publisher가 이벤트당 하나의 receive() 만 처리하도록 하려는 경우에 사용합니다. 이는 네트워크 요청 수행과 같이 중복하고 싶지 않은 값비싼 작업을 수행할 때 유용합니다.
PassthroughSubject 를 생성하는 multicast 연산자를 사용하여 값을 공유합니다.
ConnectablePublisher 이기에 connect()를 호출한 후에만 publsihing 시작됩니다.
let pub = ["First", "Second", "Third"].publisher
.map( { return ($0, Int.random(in: 0...100)) } )
.print("Random")
.multicast { PassthroughSubject<(String, Int), Never>() }
cancellable1 = pub
.sink { print ("Stream 1 received: \($0)")}
cancellable2 = pub
.sink { print ("Stream 2 received: \($0)")}
pub.connect()
Future
단일 요소를 비동기적으로 publush 합니다.
Future.Promise를 취하는 클로저로 초기화하고 클로저는 성공 또는 실패를 나타내는 결과와 함께 promise 를 호출합니다.
Future는 클래스입니다.
이행된 Promise의 결과를 current 및 future의 subscribers에게 전달합니다.
실제로 Future는 구독을 기다리지 않고 즉시 일부 작업을 수행하기 시작하면서 한 번만 작업을 수행하고 원하는 수의 subscribers에게 결과를 전달할 수 있습니다.
let future = Future<Int, Error> { fulfill in
do {
let result = try performSomeWork()
fulfill(.success(result))
} catch {
fulfill(.failure(error))
}
}
Future를 구독하지 않더라도 생성하면 클로저가 호출되어 작업이 수행됩니다.
async-await 구문과 통합하기 위해 대기 중인 호출자에게 그 값을 제공할 수 있습니다.
func generateAsyncRandomNumberFromFuture() -> Future <Int, Never> {
return Future() { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
let number = Int.random(in: 1...10)
promise(Result.success(number))
}
}
}
let number = await generateAsyncRandomNumberFromFuture().value
print("Got random number \(number).")
'Language > Swift' 카테고리의 다른 글
Swift에서 Closure는 뭘까? (0) | 2024.06.29 |
---|---|
새로워진 Swift 6 (WWDC24: What's new in Swift) (0) | 2024.06.19 |
[Swift] Reactive Programming Combine - Debugging (0) | 2024.05.19 |
[Swift] Reactive Programming Combine - Networking (0) | 2024.05.16 |
[Swift] Reactive Programming Combine - 7: Sequence (0) | 2024.05.16 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!