Contents
Chào bạn đến với Fx Studio. Đây là bài viết cuối cho loạt bài về Subject trong thế giới RxSwift. Đó là Relays.
Nếu bạn chưa biết về Subject & các loại Subject, thì có thể tham khảo các link sau:
Còn nếu mọi thứ đã ổn rồi thì …
Bắt đầu thôi!
Chuẩn bị
- Xcode 11
- Swift 5.x
- Playground
Vẫn là em Playground huyền thoại. Chúng ta vẫn còn dùng tới nó để demo code cho bài viết này. Bạn chỉ cần tạo mới 1 file Playground từ project mà đã cài đặt ngay từ bài đầu của series. Bạn có thể checkout code lại đây.
1. Relays là gì?
Relay là thành phần mới được thêm vào RxSwift. Đi kèm với đó là khai tử đi Variable , một trong nhưng Class sử dụng rất nhiều trong các project với RxSwift.
Thứ nhất, Relay là một wraps
cho một subject. Tuy nhiên, nó không giống như các subject hay các observable chung chung. Ở một số đặc điểm sau:
- Không có hàm
.onNext(_:)
để phát đi dữ liệu - Dữ liệu được phát đi bằng cách sử dụng hàm
.accept(_:)
- Chúng sẽ không bao giờ
.error
hay.completed
Thứ hai, nó sẽ liên quan tới 2 Subject khác. Do đó, ta có 2 loại Relay
PublishRelay
đó là warp của PublishSubject. Relay này mang đặc tính của PublishSubjectBehaviorRelay
đó là warp của BehaviorSubject. Nó sẽ mang các đặc tính của subject này
Đúng là không có gì mới, ngoại trừ cái tên được thay thế thôi. Chúng ta sẽ đi vào ví dụ cụ thể cho từng trường hợp nào.
2. Publish Relays
Theo trên, Publish Relay nó sẽ mang các đặc tính của Publish Subject. Và bạn cũng đã có cơ hội tìm hiểu Publish Subject trong bài viết trước. Bây giờ, bạn hãy tạo 1 file Playground mới cho demo code phần này.
2.1. Create
Bắt đầu bằng việc tạo một Publish Relay & túi rác quốc dân.
// dispose let disposeBag = DisposeBag() // error define enum MyError: Error { case anError } // relay let publishRelay = PublishRelay<String>()
Bạn sẽ có một đối tượng publishRelay
thuộc class PublishRelay
. Việc khởi tạo thì không cần cung cấp giá trị nào hết. Bạn cần phải cung cấp kiểu dữ liệu cho các phần tử được phát đi, trong trường hợp này là String
.
Nếu như bạn gặp vấn đề khi khai báo PublishRelay
thay hãy thêm import này
import RxCocoa
2.2. Emit
Tiếp theo, bạn sẽ tìm cách phát đi 1 giá trị bằng đối tượng Relay mới đó.
publishRelay.accept("0")
Lần này, sẽ khác cách Subject emit
dữ liệu đi. Bạn sử dụng .accept
thay cho .onNext
truyền thống. Chỉ là một chút thay đổi nhỏ thôi và cũng không có gì khó hết.
2.3. Subscribe
// subcribe 1 publishRelay .subscribe { print("🔵 ", $0) } .disposed(by: disposeBag) // emits publishRelay.accept("1") publishRelay.accept("2") publishRelay.accept("3") // subcribe 2 publishRelay .subscribe { print("🔴 ", $0) } .disposed(by: disposeBag) // emit publishRelay.accept("4")
Vẫn là function .subcribe()
để đăng ký tới 1 Relay. Trong ví dụ này, subscriber
sẽ nhận được các giá trị mới sau khi nó đăng ký. Còn subscribe2
, chỉ nhận được giá trị 4
thôi.
Xem kết quả của đoạn code trên như sau:
🔵 next(1) 🔵 next(2) 🔵 next(3) 🔵 next(4) 🔴 next(4)
Giờ chúng ta sang đối tượng Relay tiếp theo!
2.4. Terminate
Bạn không thể kết thúc Relay được, vì chúng không hề phát đi error
hay completed
. Việc phát đi error
& completed
thì đều bị trình biên dịch ngăn cản.
publishRelay.accept(MyError.anError) publishRelay.onCompleted()
3. Behavior Relays
Vì Behavior Relay lại mang các đặc tính của Behavior Subject. Nên cũng không có gì khó ở đây. Bạn thử thay đổi lại đoạn code trên bằng việc đổi từ PublishRelay
thành BehaviorRelay
. Và chúng ta sẽ xem xét từng đoạn code.
3.1. Create
Bắt đầu bằng dòng code khởi tạo Behavior Relay.
let behaviorRelay = BehaviorRelay<String>(value: "0")
Class tạo ra 1 Relay này là BehaviorRelay
. Tất nhiên, bạn phải cung cấp một giá trị cho value
để làm giá trị khởi tạo ban đầu cho Relay này.
3.2. Emit
behaviorRelay.accept("0")
Vẫn tương tự như Publish Relay. Sử dụng function .accept()
để phát dữ liệu đi.
3.3. Subscribe
Ta thử xem việc subscribe
như thế nào với Behavior Relay. Bạn thêm đoạn code này vào:
// subcribe 1 behaviorRelay .subscribe { print("🔵 ", $0) } .disposed(by: disposeBag) behaviorRelay.accept("1") behaviorRelay.accept("2") behaviorRelay.accept("3") // subcribe 2 behaviorRelay .subscribe { print("🔴 ", $0) } .disposed(by: disposeBag) behaviorRelay.accept("4")
Nhìn qua, nó cũng không khác các Observables & Subject. Và nó tuân theo đặc tính của Behavior Subject, sẽ luôn nhận được giá trị mới nhất khi có 1 Subscriber mới đăng ký tới.
3.4. Value
Một điều đặc biệt của Behavior Relay là bạn có thể lấy được giá trị hiện tại được lưu trữ trong Relay. Cách lấy như sau:
// current value print("Current value: \(behaviorRelay.value)")
Với toán tử .value
của Relay, thì bạn có thể truy cập ngay và sử dụng được nó. Tuy nhiên nó là read-only
mà thôi.
Thực thi đoạn code và kết quả như sau:
🔵 next(0) 🔵 next(1) 🔵 next(2) 🔵 next(3) 🔴 next(3) 🔵 next(4) 🔴 next(4) Current value: 4
.value
chính là đặc tính mà đểBehavior Relay
thay thếVariable
trong thế giới RxSwift. Bạn sẽ dùng nó nhiều khi làm việc với UIKit.
Tới đây, mình xin kết thúc bài viết về Relays và cũng là kết thúc phần Subject trong thế giới RxSwift đầy phức tạp này. Nếu có gì thắc mắc hay góp ý cho mình thì bạn có thể để lại bình luận hoặc gởi email theo trang Contact. Hẹn bạn ở các bài viết sau.
Tạm kết
Relay
là wrap một subject- Đặc điểm
- Không có
.onNext
,.onError
và.onCompleted
- Phát giá trị đi bằng
.accpet(_:)
- Không có
- Không bao giờ kết thúc
- Các class của Relay sẽ có các đặc tính của class mà nó
wrap
lại.PublishRelay
là wrap của PublishSubjectBehaviorRelay
là wrap của BehaviorSubject
Cảm ơn bạn đã đọc bài viết này!
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
- Lập trình hướng giao thức (POP) với Swift
You may also like:
Archives
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)