Giới thiệu RxJava – Phần 1

AUTHOR: hoan.nt


RxJava có lẽ là một trong những chủ đề nóng nhất trong giới Android Developer năm qua. Tuy nhiên có một vấn đề duy nhất là bạn có thể gặp khó khăn khi tiếp cận lúc ban đầu. Functional Reactive Programming khá là khó làm quen khi bạn đến từ thế giới Imperative, nhưng một khi bạn hiểu nó, nó thật tuyệt vời!

Ở đây tôi sẽ cố gắng cung cấp cho các bạn một số kiến thức cơ bản về RxJava. Tôi sẽ không giải thích tất cả mọi thứ (thực ra là tôi không thể :d ). Tôi chỉ muốn giúp bạn hứng thú với RxJava và chỉ ra cách mà nó hoạt động.

Khái niệm cơ bản

Reactive code gồm 2 phần cơ phản là  Observables  và Subscribers. Observables phát ra các items, Subscriber tiếp nhận và sử dụng các items đó.

Một Observable có thể phát ra bất kỳ số lượng các items, sau đó nó chấm dứt, hoặc bằng cách thành công (successfully completing), hoặc xảy ra lỗi (error). Đối với mỗi Subscriber nó có, một Observable gọi Subscriber.onNext() số lần bất kỳ , tiếp theo sẽ là một trong một trong hai hàm Subscriber.onComplete () hoặc Subscriber.onError() sẽ được gọi.

Điều này rất giống standard observer pattern ,nhưng nó có một sự khác biệt  – Observables thường không bắt đầu phát ra các items cho đến khi có Subscriber lắng nghe nó.

Hello, World

Hãy xem một ví dụ cụ thể. Trước tiên, hãy tạo ra một Observable.  cơ bản .

Observable của chúng ta phát ra String “Hello, world!” sau đó hoàn tất. Bây giờ hãy tạo một Subscriber  để nhận dữ liệu:

Tất cả điều này làm là in mỗi chuỗi phát ra bởi Observable.

Bây giờ chúng ta đã có myObservablemySubscriber chúng ta có thể nối chúng với nhau bằng cách sử dụng phương thức subscribe().

Khi subscription được tạo ra, myObservable sẽ  gọi phương thức onNext ()onComplete của subscriber.Kết quả là, mySubscriber  sẽ cho ra output “Hello, world!” sau đó chấm dứt.

Simpler Code

Trên đây là rất nhiều mã boilerplate chỉ để in ra  ” Hello, world!”

Đó là bởi vì tôi đã là con đường dài, do đó bạn có thể thấy chính xác những gì đang xảy ra. Có rất nhiều cách được cung cấp trong RxJava đểviệc viết code trở nên dễ dàng hơn.

Đầu tiên, chúng ta hãy đơn giản hóa Observable của chúng ta. RxJava có tích hợp nhiều cách để tạo ra Observable cho những trường hợp thường gặp. Trong trường hợp này, Observable.just () phát ra một item duy nhất sau đó hoàn thành, giống như code của chúng ta ở trên :

Tiếp theo, hãy xử lý  những cái không cần thiết trong Subscriber .Chúng ta không quan tâm về onCompleted ()hay onError(),vì vậy chúng ta có thể sử dụng một class đơn giản để xác định những việc cần làm trong onNext():

Observable.subscribe () có thể xử lý một, hai hoặc ba Action  thay thế cho  onNext(), onError(),và onComplete().Thay thế cho Subscriber  của chúng ta bên trên sẽ được như này :

Tuy nhiên, chúng ta chỉ cần tham số đầu tiên, bởi vì chúng ta đang bỏ qua onError () onComplete():

Hoặc có thể viết code như sau

Cuối cùng, chúng ta hãy sử dụng Java 8 lambdas để cho code đẹp hơn

 

Nếu bạn code Android (và do đó không thể sử dụng Java 8), Tôi khuyên bạn nên sử dụng retrolambda; nó sẽ làm code của của bạn dễ nhìn hơn, gọn gàng đi rất nhiều.

 

Transformation

Giả sử tôi muốn thêm phần chữ ký của tôi ở phần output  “Hello, world!”. Có một cách là thay đổi Observable:

Cách này bạn có thể thay đổi thông qua Observable,nhưng nó không đảm bảo thoả mãn tất cả các trường hợp – nếu tôi sử dụngcủa tôi Observable ở nhiều nơi nhưng chỉ một số chỗ tôi muốn thêm chữ ký?:

Bạn nghĩ sao về việc sửa ở Subscriber :

Câu trả lời này cũng không thoả mãn, vì các lý do khác nhau: tôi muốn Subscribers của tôi  phải được làm nhẹ càng tốt vì tôi có thể chạy chúng trên mainthread.

Sẽ tốt hơn nếu tôi có thể thay đổi String “Hello, world!” với một số bước trung gian.

Introducing Operators

Operators  có thể được sử dụng giữa Observable nguồn  và các Subscriber để control các items được  phát ra. RxJava đi kèm với một bộ sưu tập lớn Operators, nhưng tốt nhất của tôi sẽ tập trung vào chỉ một số  đơn giản trước:

Đối với bài toán của chúng ta , map() operator có thể được sử dụng để chuyển đổi một item được phát ra:

Một lần nữa, chúng ta có thể đơn giản hóa code này bằng cách sử dụng lambdas

Khá cool phải không? map() operator của chúng ta cơ bản là một Observable  biến đổi một item. Chúng ta có thể gọi nhiều map()  operator liên tiếp nếu muốn chuyển đổi data trước khi nó đến Subscriber.

More on map()

Dưới đây là một khía cạnh thú vị của map (); nó không phải phát ra các item kiểu tương tự như Observable  nguồn.

Giả sử  Subscriber của tôi không quan tâm đến xuất ra text ban đầu, nhưng thay vào đó in ra mã băm của text:

 

Thật thú vị phải không ạ – chúng ta bắt đầu với một String nhưng Subscriber  của chúng ta nhận được một Integer. Một lần nữa, chúng ta có thể sử dụng lambdas để rút ngắn code bằng

Giống như tôi đã nói bên trên , chúng ta muốn Subscriber  của chúng ta làm càng ít càng tốt. Hãy thêm vào một map() để chuyển đổi mã băm của chúng ta trở thành một String:

Chúng ta thậm chí có thể thêm chữ ký của tôi trước khi chuyển đổi data:

 

So What

Tại thời điểm này, bạn có thể nghĩ “Đó là quá nhiều code cho một việc đơn giản” Đúng đó là một ví dụ đơn giản. Nhưng có hai ý tưởng bạn nên nghĩ tới:

Key 1 # Observable Subscriber có thể làm bất cứ điều gì

Observable  có thể là một database query, các Subscriber  lấy kết quả và hiển thị chúng trên màn hình. Observable  của bạn có thể là một  stream dạng byte đọc từ internet, các Subscriber  có thể ghi nó vào disk….

Key 2 #  Các Observable Subscriber  độc lập với các bước chuyển đổi giữa chúng.

Tôi có thể gọi nhiều map() tôi muốn ở giữa Observable  và Subscriber.Hệ thống này có tính composable cao. Chúng ta rất dễ dàng để thao tác với data.

Kết hợp hai ý tưởng chính của chúng ta có thể nhìn thấy một hệ thống với rất nhiều tiềm năng. Tại thời điểm này, vì chúng ta chỉ có một operator duy nhất  map (),nên khả năng chúng ta đang bị giới hạn. Trong phần sau chúng ta sẽ tìm hiểu thêm nhiều operators mà RxJava cung cấp.

 

To be countinue!

 

 

Post Views: 1257

Comments

comments