The recent launch of Combine
has shown that the urgency of binding for Swift
. Before waiting for apple to complete it, we should still use the current RxSwift. Once you understand RxSwift, it’s easier to use Combine. In this article, I will write about the popular Combine Operators of RxSwift. To better understand its use and how it works, besides reading and practicing, you can use the RxMarbles website as a tool to make learning RxSwift easier.
CombineLatest
combineLatest:
is one of the operators you will use a lot. This operator will combine the two latest items emitted by the two observables and return them to us. The important thing to note here is that in order to receive an emit item from this operator, both source observables must generate at least 1 previous item. combineLatest
has not emit anything yet because observables emit has the shape that does not emit any item. Because of this feature, this operator is often used when this return value depends on the mix of other Observables especially when sync data between server and client, or simply enabling a button when satisfied. condition of 2 textfields boxes. Here is an example code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import Foundation import RxSwift let disposeBag = DisposeBag() let intervalObservable = Observable<NSInteger> .interval(0.1, scheduler: MainScheduler.instance) .take(3) let sourceObservableA = Observable .zip(Observable.of("?", "?", "?"), intervalObservable, resultSelector: { value1, _ in return value1 }) let sourceObservableB = Observable<NSInteger> .interval(0.2, scheduler: MainScheduler.instance) .take(3) .map { "B($0)" } Observable.combineLatest( sourceObservableA, sourceObservableB, resultSelector: { value1, value2 in print("(value1) (value2)") }).observeOn(MainScheduler.instance) .subscribe() .disposed(by: disposeBag) /* Output ? B0 ? B0 ? B1 ? B2 */ |
Zip
zip:
operator is similar to combineLatest:
but zip:
always creates pairs of events with the same index. Let’s look at the following example on Rxmarbles combineLatest:
But the other is zip:
combining items from source observables based on index
. If it is combineLatest:
at the time of emit item 2, at combineLatest:
will get 2A as shown: zip:
based on index to coordinate, it will find the second item emit from the observables below to coordinate. So when item B is emit immediately operators will return you the results.
WithLatestFrom
If the above two operators will emit when either of the source observables emits the event as long as the conditions of each operator are met. What if there were clearer constraints of this observables. In programming we often encounter a trigger event that happens to retrieve data, which is exactly what withLatestFrom:
do. This operator will treat one observables as triggers, the other observables will source. Whenever the trigger is emit, it will return that trigger and the latest item from the source observables, if the source observables have not emitted any items, there will be no emit items from the operator. Take a look and analyze this marble:
- When trigger 1 is emit, unfortunately, no data is generated at the source observable so we will not get any results in the operator.
- When item A is emit in source observables, unlike the other two operators it will not return results because? Because in
withLatestFrom:
it will be emitted only when the trigger is emit. It is not necessary to not click on the cells but already have the data returned. - When trigger 2 is emit, it will retrieve the latest item in the source observables now item A and the result in the operator will be 2A at this time.
summary
We realize that:
combineLatest:
would be preferred for updating variables depending on two or more conditions.withLatestFrom:
will be used as a trigger, and of course is very used already.zip:
likecombineLatest:
but based on index.