Contents
Chào bạn đến với Fx Studio. Bài viết lần này sẽ dẫn bạn tới với một loại Subject mới trong thế giới RxSwift. Đó là Replay Subjects.
Trước tiên, bạn cần phải nắm được các kiến thức sau:
Đó là 2 phần lý thuyết mà đi theo bạn khá lâu đó. Còn nếu mọi thứ đã ổn rồi thì …
Bắt đầu thôi!
Chuẩn bị
-
- Xocde 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. Khái niệm Replay Subjects
Đầu tiên, chúng ta hay đi sơ qua khái niệm của Replay Subjects là gì với việc mô tả bằng sơ đồ marble.
Vẫn là cái sơ đồ huyền thoại và chúng ta cũng thấy là khá tương đồng với 2 loại Subject trước (Publish & Behavior). Điểm khác biệt là bạn hãy tập trung vào thời điểm sau khi subscribe()
lần thứ 2 tới Subject. Khi đó, subscriber nhận được 2 giá trị.
Vậy Replay Subject là gì?
Đây cũng là một loại Subject. Đặc điểm của loại subject này, khi phát đi các giá trị thì đồng thời nó lưu lại các giá trị đó trong bộ đệm của mình. Và khi có một subscriber đăng kí tới, subject này sẽ phát đi các giá trị trong bộ đêm của nó cho subscriber đó.
Ta có các đặc điểm sau của loại Subject này:
- Khởi tạo bằng kích thước bộ đệm của subject
- Khi phát đi 1 phần tử thì đồng thời lưu trữ nó vào bộ đệm
- Khi có subscriber mới tới thì sẽ nhận được toàn bộ phần tử trong bộ đệm
2. Hoạt động
2.1. Create Replay Subjects
Chuyển sang xem code ví dụ cho dễ hiểu hơn nào. Bắt đầu bằng việc khai báo 1 Replay Subject. Bạn hãy tạo thêm 1 file Playground để demo code cho phần này. Hoặc dùng lại ở bài trước cũng được. Không quá nhiều code đâu.
Tạo đối tượng subject mới nào.
let subject = ReplaySubject<String>.create(bufferSize: 2)
Phân tích:
- Class sử dụng là
ReplaySubject
- Kiểu giá trị được phát đi là
String
- Bộ đệm lưu trữ tối đa là 2 phần tử
Ngoài ra, muốn bộ đệm lưu trữ tất cả các giá trị, thì bạn hãy khởi tạo với hàm sau:
let subject = ReplaySubject<String>.createUnbounded()
Bạn nhớ khai báo thêm túi ra quốc dân để dùng cho các ví dụ tiếp theo sau.
2.2. Emit
// emit subject.onNext("1") subject.onNext("2") subject.onNext("3")
Vẫn là cách emit
truyền thống giống như Publish Subject & Behavior Subject. Bạn chỉ cần gọi toán tử .onNext
và truyền giá trị vào. Vậy là xong!
2.3. Subscribe
Giờ chúng ta tiến hành phát đi vài dữ liệu & subscribe lần đầu, để xem các giá trị nhận được là gì? Bạn thêm đoạn subscribe này vào:
// subcribe 1 subject .subscribe { print("🔵 ", $0) } .disposed(by: disposeBag)
Okay, thực thi đoạn code và xem kết quả:
🔵 next(2) 🔵 next(3)
Vì với khai báo bufferSize = 2,
nên bộ đệm của subject chỉ chứa được tối đa 2 phần tử. Do đó, không nhận được giá trị 1
.
Chúng ta tiếp tục phát & subscribe lần 2 để xem ra sao.
// emit subject.onNext("4") // subcribe 2 subject .subscribe { print("🔴 ", $0) } .disposed(by: disposeBag)
Subscriber 1 sẽ nhận được giá trị 4
và subscriber 2 chỉ nhận được 3
và 4
.
🔵 next(2) 🔵 next(3) 🔵 next(4) 🔴 next(3) 🔴 next(4)
Khá là EZ!
2.4. Terminate
Còn với error
thì như thế nào. Ta lại tiếp tục ví dụ với emit error
và subscribe lần thứ 3
// error
subject.onError(MyError.anError)
// subcribe 3
subject
.subscribe { print("🟠 ", $0) }
.disposed(by: disposeBag)
Kết quả ra như sau:
🔵 next(2) 🔵 next(3) 🔵 next(4) 🔴 next(3) 🔴 next(4) 🔵 error(anError) 🔴 error(anError) 🟠 next(3) 🟠 next(4) 🟠 error(anError)
Bạn sẽ thấy subscriber thứ 3 sẽ nhận đầy đủ 2 giá trị trong bộ đêm và kèm theo giá trị error
của subject. Ngoài ra, 2 subscriber trước đó vẫn nhận error
.
Điều này vô tình gây ra một rắc rối. Khi subject đã kết thúc rồi mà các subscriber vẫn nhận được giá trị trong bộ đệm.
Tiếp tục, với việc dispose
luôn subject để xem như thế nào.
// error subject.onError(MyError.anError) // dispose subject.dispose() // subcribe 3 subject .subscribe { print("🟠 ", $0) } .disposed(by: disposeBag)
Tới đây thì kết quả có chút thay đổi.
🔵 next(2) 🔵 next(3) 🔵 next(4) 🔴 next(3) 🔴 next(4) 🔵 error(anError) 🔴 error(anError) 🟠 error(Object `RxSwift.(unknown context at $12d143990).ReplayMany<Swift.String>` was already disposed.)
Đối tượng subscriber thứ 3 không nhận được các dữ liệu từ bộ đệm nữa.
Đó là cách kết thúc đau khổ nhanh nhất, tránh nhiều phiền hà về sau khi bạn muốn Replay Subject không phát lại bất cứ gì cho các subscriber mới.
2.5. Demo code
Cũng hơi dài cho việc hướng dẫn bạn bằng code theo kiểu step by step
. Và mời bạn xem lại toàn bộ code để có cái nhìn tổng quát nhất nha. Ahihi!
let disposeBag = DisposeBag() enum MyError: Error { case anError } let subject = ReplaySubject<String>.create(bufferSize: 2) // emit subject.onNext("1") subject.onNext("2") subject.onNext("3") // subcribe 1 subject .subscribe { print("🔵 ", $0) } .disposed(by: disposeBag) // emit subject.onNext("4") // subcribe 2 subject .subscribe { print("🔴 ", $0) } .disposed(by: disposeBag) // error subject.onError(MyError.anError) // dispose subject.dispose() // subcribe 3 subject .subscribe { print("🟠 ", $0) } .disposed(by: disposeBag)
Bạn nhớ test thử việc unlimited
bộ đệm của Subject thì như thế nào.
let subject = ReplaySubject<String>.createUnbounded()
OKAY! Mình xin kết thúc bài viết này tại đâ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
ReplaySubject
là subject mà sẽ phát lại các giá trị đã phát cho các subscriber mới đăng kí tới- Số lượng của các giá trị phát lại tuỳ thuộc vào các cấu hình bộ đệm lúc khởi tạo subject
- Ngay cả khi subject phát đi
error
haycompleted
thì các subscriber mới vẫn sẽ nhận được đầy đủ các giá trị trong bộ đệm vàerror
haycompleted
cuối cùng đó. - Khi sử dụng toán tử
dispose()
củasubject
thì toàn bộ mọi thứ sẽ được xoá hết. Nên các subscriber mới lúc đó sẽ không nhận được gì ngoàierror
.
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
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- 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
You may also like:
Archives
- September 2024 (1)
- 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)