我已經使用 RxSwift 有一段時間了,剛剛切換到 Combine 并且我正試圖解決這個特定的.filter行為。這是一個簡短的游樂場示例:
import Combine
let publisher = [1, 2, 3, 4, 5]
.publisher
.share()
let filter1 = publisher
.filter { $0 == 1 }
.print("filter1")
let filter2 = publisher
.filter { $0 == 2 }
.print("filter2")
Publishers
.Merge(filter1, filter2)
.sink {
print("Result is: \($0)")
}
輸出是
filter1: receive subscription: (Multicast)
filter1: request unlimited
filter1: receive value: (1)
Result is: 1
filter1: receive finished
filter2: receive subscription: (Multicast)
filter2: request unlimited
filter2: receive finished
讓我感到驚訝的是它Result is: 2從未被呼叫,因為流結束了。我可以洗掉.share()運算子,這將導致我期望的同時收到兩個值
filter1: receive subscription: ([1])
filter1: request unlimited
filter1: receive value: (1)
Result is: 1
filter1: receive finished
filter2: receive subscription: ([2])
filter2: request unlimited
filter2: receive value: (2)
Result is: 2
filter2: receive finished
但是如果我的發布者是 API 呼叫并且我不想創建重復的網路請求怎么辦?這正是我現在試圖處理的情況,這也是我需要使用.share()運算子的原因。
任何更好的解釋為什么會發生這種情況以及如何處理您想要過濾流、在每個流中執行單獨的邏輯然后將結果合并在一起的情況?
uj5u.com熱心網友回復:
所以這里發生了一些不同的事情。
首先,該[1, 2, 3].publisher作品比不同Observable.from([1, 2, 3])。后者每個周期發出一次值,而前者則背靠背地發出所有值。Publisher 示例在 Rx 中更像這樣:
Observable<Int>.create { observer in
[1, 2, 3, 4, 5].forEach {
observer.onNext($0)
}
observer.onCompleted()
return Disposables.create()
}
因此,在這種Observable.from情況下,在訂閱 filter2 observable 時,發射還沒有完成。因此,即使您省略了share()“Result is: 1”和“Result is: 2”也會被發出。
其次,share()操作員的作業方式也不同。默認情況下,一旦所有訂閱都被釋放(這是一個參考計數共享),RxSwift 共享運算子將重置 Observable。在Combine 情況下,共享運算子使發布者可連接,然后連接到它。本質上,它與.share(replay: 0, scope: .forever)RxSwift 中的運算子相同(我在 Rx BTW 中從未需要過這種操作)。
所以相當于你貼的Combine代碼的Rx代碼其實是這樣的:
let observable = emitSequence([1, 2, 3, 4, 5])
.share(replay: 0, scope: .forever)
let filter1? = observable
.filter { $0 == 1 }
.debug("filter?1")
let filter2? = observable
.filter { $0 == 2 }
.debug("filter?2")
Observable.merge(filter1?, filter2?)
.subscribe(onNext: {
print("Result? is: \($0)")
})
func emitSequence<S>(_ sequence: S) -> Observable<S.Element> where S: Sequence {
Observable.create { observer in
sequence.forEach {
observer.onNext($0)
}
observer.onCompleted()
return Disposables.create()
}
}
所有這些都表明處理 API 呼叫的實際方面很好。在這種情況下,假設是呼叫不會立即回傳(這將需要至少一個周期),因為它是一次性的,只要你確保你沒有重新訂閱可觀察的,但事實上,share()沒有按'不重置不是問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/360674.html
上一篇:OpenLayers通過Vue無服務器應用程式中的promise/await同步執行
下一篇:承諾值的總和和回傳承諾JS
