Trong phần này mình sẽ giới thiệu cho các bạn tiếp theo về Operator của RXSwift.Gồm có 6 nhóm chính :
- Filter
- Transform
- Combine
- Create
- Utilities
- Error Handling
1. Filter : chúng ta sẽ lọc observable trước khi bắn trả về bên subscribe.
- Filter : 1 closure cho phép bạn lọc theo điều kiện
let disposeBag = DisposeBag() Observable.of(1, 10, 3, 5, 2, 13) .filter { integer in integer > 10 // lọc các số lớn hơn 10 } .subscribe(onNext: { print($0) }) .addDisposableTo(disposeBag)// 10 13
- IgnoreElements : Bỏ qua hết các event.onNext chỉ nhận event.onComplete
let publish = PublishSubject<String>()
let disposeBag = DisposeBag()
strikes
.ignoreElements()
.subscribe { _ in
print("Print!")
}
.addDisposableTo(disposeBag)
publish.onNext("1")
publish.onNext("2")
publish.onCompleted() // Tới đây mới Print!
- Skip(number) : Bỏ qua những event ban đầu theo số number.
let disposeBag = DisposeBag() Observable.of(11, 12, 13, 14, 15, 16) .skip(4) .subscribe(onNext: { print($0) }) .addDisposableTo(disposeBag)// 15 16
- Take(number) : ngược lại với skip, là những chỉ nhận những event ban đầu theo số number.
let disposeBag = DisposeBag() Observable.of(11, 12, 13, 14, 15, 16) .take(1) .subscribe(onNext: { print($0) }) .addDisposableTo(disposeBag)// 11
- TakeUntil : thực hiện observer đến khi có 1 tín hiệu khác đến như : từ 1 observable khác, hay view dealloc…
let disposeBag = DisposeBag() let subject = PublishSubject<String>() let subjectCancel = PublishSubject<String>()subject //Đợi chi có tín hiệu từ subjectCancel .takeUntil(subjectCancel) // có thể là (self.rx.deallocated) .subscribe(onNext: { print($0) }).addDisposableTo(disposeBag)subject.onNext("next1") subject.onNext("next2") subjectCancel.onNext("cancel") subject.onNext("next3")// next1 next2 cancel
- DistinctUntilChanged : chỉ nhận khi value khác với value phía trước nó
// Ví dụ : như trong thanh search khi user nhập chỉ lấy query với value mới// Ví du : A A B N N M M -> chỉ nhận : A B N M let searchResults = searchText .distinctUntilChanged .flatMapLatest { query in }
- Debounce vs Throttle : là các timer dùng để nhận hoặc skip trong 1 khoảng thời gian nào đó.
let searchResults = searchText
.throttle(2, $.mainScheduler) // .debounce(2, $.mainScheduler)
.distinctUntilChanged
.flatMapLatest { query in
}
2 operator đó khác nhau ở chỗ :
+ throttle : giá trị từ search text chỉ nhận khi các khoảng cách user nhận text cách nhau 2s, (skip(timer≥2s)). ví dụ : click button
+ debounce : giá trị từ search text chỉ nhận khi trong khoảng 2s đó user không nhập 1 input nào tiếp theo, nếu user nhập trong khoảng 2s đó , nó sẽ reset timer lại, với thời gian băn đầu = với event input mới nhất.(skip (ko có event)(timer≥2s)). ví dụ : search text
+ throttle : giá trị từ search text chỉ nhận khi các khoảng cách user nhận text cách nhau 2s, (skip(timer≥2s)). ví dụ : click button
+ debounce : giá trị từ search text chỉ nhận khi trong khoảng 2s đó user không nhập 1 input nào tiếp theo, nếu user nhập trong khoảng 2s đó , nó sẽ reset timer lại, với thời gian băn đầu = với event input mới nhất.(skip (ko có event)(timer≥2s)). ví dụ : search text
2.Transform : chuyển đổi kiểu dữ liệu từ observable, trước khi bắn ra observer
- map : chuyển đổi observable này qua observable loại khác.
// Nhân 2 mỗi số Observable<Int> -> Observable<Int> Observable.of(1,2,3) .map { (number) in number * 2 } // Qua string : Observable<Int> -> Observable<String> .map { (json) in "number :\(number)" }// Chuyển tử Bool -> Intlet observable = Observable<Bool>.create { (observer) -> Disposable in observer.onNext(true) return NopDisposable.instance }let intObservable : Observable<Int> = observable.map { (element) -> Int in if element { return 1 } else { return 0 } }intObservable.subscribeNext { (intElement) in print(intElement) }.addDisposableTo(disposeBag)
- Flatmap/FlatmapLatest :
+ Flatmap chuyển đổi các phần tử của observable thành một sequence observable, và nó tách ra từng phần chuyển đổi và merge chúng lại thành 1 observable.
+ Còn FlatmapLatest giống như Flatmap nhưng khác ở chỗ FlatmapLatest sẽ tự động chuyển qua observable mới nhất (ex : car2), và unsubscribe observable cũ (ex : car).
Ví dụ :
Chuyển đổi từ Car observable -> speed observable
Chuyển đổi từ Car observable -> speed observable
let disposeBag = DisposeBag()struct Car { var speed: Variable<Int> }let carSubject = PublishSubject<Car>() carSubject.asObservable() .flatMap { $0.speed.asObservable() } .subscribe(onNext: { print("speed: \($0)") }) //score: 80 .disposed(by: disposeBag)let car = Car(speed:Variable(200)) let car2 = Car(speed:Variable(400)) carSubject.onNext(car) car.speed.value = 300 carSubject.onNext(car2) car.speed.value = 350 // => đã obserser qua card2, card bị ignore car2.speed.value = 500//Dùng flatMap speed: 200 speed: 300 speed: 400 speed: 350 speed: 500//Dùng flatMapLatest => bị mất speed: 350 speed: 200 speed: 300 speed: 400 speed: 500let sequence1 = Observable<Int>.of(1,2,3,4) let sequence2 = Observable<Int>.of(5,6,7,8) let sequenceOfSequences = Observable.of(sequence1,sequence2) sequenceOfSequences.flatMap{ return $0 }.subscribe(onNext:{ print($0) }) //1 2 5 3 6 4 7 8
3.Combine : Các toán tử kết hợp
- StartWith : thêm giá trị đầu tiên.
Observable.of(2, 3) .startWith(1) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag)// 1,2,3
- Concat : Nối 1 cụm này với 1 cụm khác, đợi tất cả đã complete.
Observable.of(1,2, 3).concat(Observable.of(4,5, 6)) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag)// 1 2 3 4 5 6
- Merge : Nội cụm nhưng theo chiều dọc, cứ cố bất kì element mới là nối vào chuỗi kết hợp.
Observable.merge([ Observable.of(1,2, 3),Observable.of(4,5, 6)]) .subscribe(onNext: { print($0) }) .disposed(by: disposeBag)// 1 4 2 5 3 6
- combineLatest : kết hợp element của observable này với element observable khác mới nhất, 2 element kết hợp luôn là mới nhất.
Observable.combineLatest(Observable.of(1,2, 3),Observable.of(4,5, 6)){ (number1,number2) -> String in "\(number1) - \(number2)" } .subscribe(onNext: { print($0) }) .disposed(by: disposeBag)//1 - 4 //2 - 4 //2 - 5 //3 - 5 //3 - 6
- Zip : kết hợp theo cặp các element, và các element chỉ kết hợp 1 lần.
Observable.zip(Observable.of(1,2, 3),Observable.of(4,5,6,7)) { (number1,number2) -> String in "\(number1) - \(number2)" } .subscribe(onNext: { print($0) }) .disposed(by: disposeBag)// 1 - 4 // 2 - 5 // 3 - 6
- Reduce : tích trữ, tổng hợp, cộng dồn , sẽ bắn ra kết quả cuối cùng.
// Cộng dồn các số với giá trị bắt đầu = 0 let source = Observable.of(1, 2, 3, 4, 5) let observable = source.reduce(0, accumulator: { $0 + $1 }) observable.subscribe(onNext: { value in print(value) // 15 })// So sánh dồn với các giá trị bool let source2 = Observable.of(true, true, false, true) let observable2 = source2.reduce(true, accumulator: { $0 && $1 }) observable2.subscribe(onNext: { value in print(value) // false })
- Scan : giống reduce là cộng dồn lại những mỗi kết quả cộng được sẽ bắt ra element mới cho bên subscribe nhận.
let source3 = Observable.of(1, 2, 3, 4, 5) let observable3 = source3.scan(0, accumulator: { $0 + $1 }) observable3.subscribe(onNext: { value in print(value) })//1 //3 //6 //10 //15
Trong
phần này mình đã giới thiệu bạn 3 nhóm operator : Filter, Transform,
Combine .Sang phần sau mình sẽ giới thiệu tiếp 3 nhóm còn lại.
Comments
Post a Comment