RxSwift 7: Disposing và terminating

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

Trong bài trước, chúng ta đã nghiên cứu cách tạo các observables ở những kiểu khác nhau. Ở bài chúng ta nghiên cứu phần xử lý và chấm dứt chúng.

  RxSwift 10: Làm việc với PublishSubjects
  RxSwift 2: Khái niệm cơ bản về lập trình bất đồng bộ

Hãy nhớ rằng 1 observable sẽ không làm gì cho đến khi nó nhận được đăng ký(subscription). Một đăng ký kích hoạt nó phát ra các sự kiện, cho đến khi nó tạo ra 1 sự kiện .error hoặc .completed để kết thúc. Bạn có thể đăng ký nó và chấm dứt nó. Cùng xem ví dụ sau:

example(of: "dispose") {
  // 1
  let observable = Observable.of("A", "B", "C")
  // 2
  let subscription = observable.subscribe { event in
// 3
    print(event)
  }
}
  1. Tạo 1 observable gồm các string
  2. Đăng ký vào observable, phát ra các sự kiện
  3. Hiển thị các sự kiện phát ra

Kết quả:

--- Example of: dispose ---
next(A)
next(B)
next(C)
completed

Để hủy 1 subscribe, ta thêm dispose() cho nó. Và nó ngừng phát ra sự kiện. Thêm đoạn code này vào cuối chương trình:

subscription.dispose()

Quản lý hủy đăng ký rất tẻ nhạt, cho nên RxSwift cung cấp cho chúng ta công cụ để hủy là hàm .disposed(by:), và sẽ tự động gọi dispose mỗi khi đăng ký bị hủy. Cùng xem đoạn code sau:

example(of: "DisposeBag") {
  // 1
  let disposeBag = DisposeBag()
// 2
  Observable.of("A", "B", "C")
    .subscribe { // 3
print($0) }
    .disposed(by: disposeBag)
}
  1. Tạo 1 disposeBag
  2. Tạo 1 observable
  3. Subscibe và hiển thị các sự kiện của nó
  4. Trả về giá trị cho disposeBag

Đây là mẫu mà bạn sẽ sử dụng thường xuyên nhất, tạo và đăng ký 1 observable đồng thời thêm đăng ký vào xử lý disposeBag. Khi bạn quên đăng ký disposeBag cho nó có thể gây rò rỉ bộ nhớ. Tuy nhiên đừng lo lắng, trình biên dịch sẽ cảnh báo cho bạn.

Trong các ví dụ trước, bạn quan sát các sự kiện thông qua sự kiện .next. Cùng xem ví dụ sau:

example(of: "create") {
    Observable<String>.create { observer in
      // 1
      observer.onNext("1")
      // 2
      observer.onCompleted()
    // 3
      observer.onNext("?")
    // 4
      return Disposables.create()
    }
}
  1. Thêm sự kiện .next cho observer
  2. Thêm sự kiện .completed
  3. Thêm sự kiện onNext cho Observer
  4. Trả về 1 disposable

Bạn có nghĩ phần tử onNext “?” có emmit cho subscibers không? Cùng xem ví dụ sau:

example(of: "create") {
    let disposeBag = DisposeBag()
    
    Observable<String>.create { observer in
      // 1
      observer.onNext("1")
      // 2
      observer.onCompleted()
    // 3
      observer.onNext("?")
    // 4
      return Disposables.create()
    }.subscribe(
        onNext: { print($0) },
        onError: { print($0) },
        onCompleted: { print("Completed") },
        onDisposed: { print("Disposed") }
      )
    .disposed(by: disposeBag)
}

Kết quả như sau:

--- Example of: create ---
1
Completed
Disposed

Vì sự kiện complete đã phát ra cho nên sự kiện 3 không thể phát ra nữa. Điều gì sẽ xảy ra khi bạn thêm 1 sự kiện error cho nó? Cùng thêm đoạn code sau vào đầu file:

enum MyError: Error {
  case anError
}

Và thêm đoạn code sau vào giữa .onNext và .onCompleted:

observer.onError(MyError.anError)

Kết quả như sau:

--- Example of: create ---
1
anError
Disposed

Điều gì sẽ xảy ra khi chúng ta không emit ra sự kiện onCompleted và .error cũng như không đăng ký với disposeBag? Sửa lại đoạn code như sau:

example(of: "create") {
  enum MyError: Error {
    case anError
  }
  let disposeBag = DisposeBag()
  Observable<String>.create { observer in
    // 1
    observer.onNext("1")
//    observer.onError(MyError.anError)
    // 2
//    observer.onCompleted()
// 3
    observer.onNext("?")
// 4
    return Disposables.create()
  }
  .subscribe(
    onNext: { print($0) },
    onError: { print($0) },
    onCompleted: { print("Completed") },
    onDisposed: { print("Disposed") }
)
//   .disposed(by: disposeBag)
}

Kết quả như sau:

--- Example of: create ---
1
?

Xin chúc mừng, bạn vừa tạo ra 1 leak memory! Observable sẽ không bao giờ kết thúc, dispose sẽ không bao giờ được sử dụng.

Trong bài tiếp theo chúng ta sẽ học cách tạo 1 observable factories.

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 swift hấp dẫn trên TopDev