Contents
Chào bạn đến với Fx Studio. Bài này sẽ đi vào một chủ đề nhỏ trong vũ trụ RxSwift. Đó là việc tạo ra một Observable. Có bao nhiêu cách và sử dụng chúng như thế nào?
Cũng như các bài viết trước, bài này yêu cầu bạn phải biết về Observable đã. Còn nếu bạn chưa đọc qua nó, thì truy cập link dưới để được phổ cập kiến thức.
Còn mọi việc đã ổn rồi, thì …
Bắt đầu thôi!
Chuẩn bị
- Xcode 11
- Swift 5.x
- Playground
Bài viết này, bạn không cần phải chuẩn bị gì nhiều. Có thể tận dụng lại các Playground của các bài trước cũng được. Hoặc tạo thêm mới 1 cái cho nó xịn sò. Nếu bạn quên link checkout source code, thì có thể checkout tại đây.
1. Creating an Observable
Ở bài trước với Observable đại cương, bạn cũng đã tạo được Observable bằng 3 toán tử huyền thoại just
, of
& from
. Nhưng đó là các toán tử RxSwift được bọc lại trong các API của ReactiveX
. Và đôi khi, bạn chuyển sang Rx cho ngôn ngữ khác lại không thấy chúng nó ở đâu.
Do đó, chúng ta quay về vũ trụ gốc là ReactiveX
, thì có 3 cách tạo cơ bản như sau:
-
- create
- just
- deferred
Phần việc tiếp theo là đi vào từng toán tử thôi. EZ!
2. create
create()
– the most flexible way to create an Observable
Thật là không thể chối từ được vai trò của nó. Ngay cả cái tên là create
thì cũng nói lên tất cả rồi. Và nó thực sự là rất linh hoạt. Bạn sau này sẽ dùng nó rất thường xuyên. Khi nào, bạn muốn tạo ra 1 Observable ở bất kì đâu, nó sẽ giúp cho bạn thực hiện được tốt nhất.
Nó cân tất các loại code đồng bộ và bất đồng bộ. Hoặc bạn nhẹ nhàng đặt nó vào 1 function non-Rx cũng không sao.
Cuối cùng, bạn có thể xác định hành vi cho các việc next
, error
& completed
trong closure của create
. Đây là điểm tối quan trọng nhất. Bạn sẽ dùng nó để viết lại logic của 1 function non-Rx thành function Rx.
- Cách dùng:
- Ném cho nó cái closure cho tham số
- return về 1 Disposables
return Observable.create { observer in return Disposables.create() }
Ví dụ cho việc sử dụng creater
- Tạo 1 function với giá trị trả về là
Observable<Void>
func doAction() -> Observable<Void> { return Observable<Void>.create( ... ) }
- Hoàn thành với
create
return Observable.create { observer in self.someAsyncOpertation { success: Bool in if success { observer.onNext(()) //It sends a void into the AnyObserver<Void> observer.onCompleted() } else { observer.onError(MyError()) } } return Disposables.create() }
Quá EZ!
3. just
just()
– the easiest way to wrap a value
Giờ tới cái toán tử toán linh hoạt nhất để biến 1 giá trị thành một Observable. Nó được xem là cầu nối cho 2 thế giới : Rx & Non-Rx. Và điều hiển nhiên, Observable mà nó tạo ra sẽ phát đi duy nhất mỗi giá trị kia. Sau đó, Observable sẽ tự kết thúc.
Và đã vui thì có bạn có bè cùng vui chung. Nên ngoài just
, ta có thêm các anh chị em của nó như là:
-
empty
: không phát gì hết mà kết thúccompleted
never
: không phát ra gì cả. Kể cả error hay completederror
: phát ra mỗi error và kết thúc
(Các ví dụ cho nó thì bạn xem lại ở các bài trước nha.)
4. deferred
deferred()
– defer calculation until subscription
4.1. waiting
Với anh just
trên, bạn phóng ngay giá trị đó đi. Nhưng nếu bạn cần phải xử lý dữ liệu trước khi phóng đi. Và nếu như lần nữa, việc xử lý của bạn lại tốn quá nhiều thời gian. Nhất là công việc đó nó sẽ block thread. Thì …
Toang chắc!
Ví dụ điển hình là xin phép quyền truy cập tới một số service trong thiết bị
func permissionObservable() -> Observable<PHAuthorizationStatus> { return .just(PHPhotoLibrary.authorizationStatus()) }
Lúc này, sẽ có 1 Alert hiện ra và đợi người dùng cho phép. Rắc rối cũng từ đây mà ra. Rất có thể app của bạn sẽ crash rồi. Vậy tốt nhất là chờ người dùng cho phép rồi hãy emit
dữ liệu đi.
Giải quyết nó như thế này nè
func permissionObservable() -> Observable<PHAuthorizationStatus> { return Observable.deferred { return .just(PHPhotoLibrary.authorizationStatus()) } }
Tác dụng của nó trì hoãn việc phát dữ liệu emit
cho subscriber khi đăng kí tới Observable. Vì bạn cũng đã biết rằng Observable sẽ phát dữ liệu ngay khi có 1 subcription tới nó. Và bạn sẽ có đủ thời gian để giải quyết rồi nha.
4.2. Observable factories
Và tại sao bạn không chủ động cung cấp 1 hoặc nhiều Observable mới cho mỗi subscriber. Thay vì phải chờ đợi.
Ta bắt đầu xem qua ví dụ sau:
let bag = DisposeBag()
var flip = true
let factory = Observable<Int>.deferred {
flip.toggle()
if flip {
return Observable.of(1)
} else {
return Observable.of(0)
}
}
Trong đó:
bag
là túi rác quốc dânflip
là cờ lật qua lật lại- Nếu
flig == true
thì trả về 1 Observable với giá trị phát đi là1
- Ngược lại là
0
Ở đây, mỗi lần return là 1 Observable mới. Tất nhiên, để làm được việc này, ta sử dụng toán tử .deferred
để tạo ra 1 Observable, mà người ta gọi là Observable factories
.
.deferred
tạo ra 1 Observable nhưng sẽ trì hoãn nó lại. Và nó sẽ được return
trong closure xử lí được gán kèm theo.
Nhìn qua thì Observable factories cũng giống như các Observable bình thường khác. Bên ngoài, bạn sẽ không phân biệt được nó có gì khác lạ. Xem tiếp cách sử dụng của nó
for _ in 0...10 {
factory.subscribe(
onNext: { print($0, terminator: "") })
.disposed(by: bag)
print()
}
Kết quả: Lặp từ 0 đến 10, cứ mỗi bước in ra giá trị nhận được. Đây là cách đếm chẵn lẻ cao cấp bằng RxSwift
0
1
0
1
0
1
0
1
0
1
0
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.
Tạm kết
create
là cách linh hoạt nhất để tạo ra một Observablejust
sẽ giúp bạn biến 1 giá trị thành 1 Observable. Ngoài ra, nó còn những người anh em thân thương của mình nữa. Với mỗi loại cho một nhiệm vụ đặc biệt.deferred
trì hoãn việc phát dữ liệu khi có 1 subscription tới. Giúp cho bạn có thời gian để xử lý dữ liệu trước khi gởi đi
Tham khảo: http://adamborek.com/creating-observable-create-just-deferred/
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)