RxSwift 10: Làm việc với PublishSubjects

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Trong bài 9, chúng ta đã tìm hiểu qua cách hoạt động của các loại subjects. Trong bài này, chúng ta sẽ nghiên cứu cách sử dụng các loại subjects trông qua source code cụ thể.

  Sử dụng publisher confirm trong RabbitMQ
  RxSwift 10: Làm việc với PublishSubjects
thay vì biến public?”]

Làm việc với PublishSubjects

Cách hoạt động của PublishSubjects

Ở hình trên, chúng ta có 3 đường thẳng thể hiện cho 3 subscribes đăng ký các sự kiện trong thời gian thực. Trong đoạn code bài trước, đường thẳng đầu tiên thể hiện subscribe 1. Sau khi đăng ký, Publish subjects emit 1 sự kiện string là “1”. Lúc đó subscriptionOne nhận được.

Chúng ta thêm đoạn code sau để đăng ký tiếp subscriptionTwo:

example(of: "PublishSubject") {
    let subject = PublishSubject<String>()
    subject.onNext("Co ai nghe tui noi khong?")
    let subscriptionOne = subject
        .subscribe(onNext: { string in
            print(string)
        })
    subject.on(.next("1"))

    // Add subscription two
    let subscriptionTwo = subject
      .subscribe { event in
        print("2)", event.element ?? event)
      }
}

Kết quả chạy PlayGround như sau:

--- Example of: PublishSubject ---
1

Ở đây chúng ta thấy mặc dù đã đăng ký nhưng subscriptionTwo không hề emit ra sự kiện nào. Điều này dễ dàng thấy rằng, 1 PublishSubject sẽ chỉ thực sự phát ra sự kiện cho subscriptionTwo sau khi nó đã đăng ký.

Tiếp tục thêm đoạn code sau:

subscriptionOne.dispose()
subject.onNext("4")

Kết quả chạy chương trình:

--- Example of: PublishSubject ---
1
2) 4

Lúc này subscriptionOne đã dispose, cho nên nó không thể tiếp tục nhận sự kiện từ PublishSubject.

Hãy thêm đoạn code sau:

// 1
    subject.onCompleted()
    // 2
    subject.onNext("5")
    // 3
    subscriptionTwo.dispose()
    let disposeBag = DisposeBag()
    // 4
    subject
      .subscribe {
        print("3)", $0.element ?? $0)
      }.disposed(by: disposeBag)

    subject.onNext("?")
  1. Đầu tiên gửi sự kiện hoàn thành completed cho subject
  2. Gửi 1 sự kiện “5”. Lúc này không có sự kiện nào được in ra, bởi vì subject đã thực sự kết thúc.
  3. dispose subscriptionTwo báo cho nó biết là đã kết thúc việc lắng nghe
  4. Tạo 1 subscription cho subject. Thêm disposeBag cho nó.
  5. Gửi tiếp sự kiện “?”. Thì subject báo nó đã hoàn thành, nên nó không hiển thị thêm “?” nữa. Tuy nhiên subscriptionOne, subscriptionTwo vẫn hiển thị sự kiện đã hoàn thành mặc dù nó đã dispose. Do vậy, bạn phải chú ý khi sử dụng PublishSubject khi xử lý.

Source đầy đủ:

import UIKit
import RxSwift

public func example(of description: String, action: () -> Void) {
    print("\n--- Example of:", description, "---")
    action()
}

example(of: "PublishSubject") {
    let subject = PublishSubject<String>()
    subject.onNext("Co ai nghe tui noi khong?")
    let subscriptionOne = subject
        .subscribe(onNext: { string in
            print("1)" + string)
        })
    subject.on(.next("1"))

    // Add subscription two
    let subscriptionTwo = subject
      .subscribe { event in
        print("2)", event.element ?? event)
      }

    subscriptionOne.dispose()
    subject.onNext("4")

    // 1
    subject.onCompleted()
    // 2
    subject.onNext("5")
    // 3
    subscriptionTwo.dispose()
    let disposeBag = DisposeBag()
    // 4
    subject
      .subscribe {
        print("3)", $0.element ?? $0)
      }.disposed(by: disposeBag)

    subject.onNext("?")
}

Đôi khi bạn muốn khi 1 subscription đăng ký mới muốn biết các event trước đó là gì. Chúng ta sẽ cùng nghiên cứu trong bài 11 về BehaviorSubjects.

Source code tham khảo tại: https://github.com/lexuanquynh/RxLearning.git

Nhớ chạy pod install nhé!

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm code swit hấp dẫn trên TopDev