BehaviorSubject, ReplaySubject và AsyncSubject – khác nhau thế nào?

RxJS là một thư viện rất phổ biến cho việc xử lý luồng dữ liệu bất đồng bộ. Trong đó chúng ta hay dùng tới Subject, dùng để gửi dữ liệu multicast tới nhiều Observables, nghĩa là các supscription sẽ nhận được cùng giá trị dữ liệu. Tuy nhiên, RxJS còn cung cấp các Subject khác là BehaviorSubject, ReplaySubject và AsyncSubject.

Vậy điểm khác nhau của 3 loại Subject này là gì?

  • BehaviorSubject: subscriber sẽ nhận được giá trị cuối cùng mà Subject emit khi nó bắt đầu subscribe.
  • ReplaySubject: Cũng tương tự BehaviorSubject, tuy nhiên dữ liệu đã emit được lưu lại với số lượng tùy ý (được cấu hình lúc khai báo). Khi subscriber bắt đầu subscribe thì nó sẽ nhận được số lượng giá trị đã emit trước đó tương ứng.
  • AsyncSubject: Chỉ emit giá trị cuối cùng lúc nó complete bởi hàm complete().

Dưới đây là ví dụ cụ thể để bạn dễ hình dung

import * as Rx from "rxjs";

const subject = new Rx.Subject();

subject.next(1);
subject.next(2);

subject.subscribe((data) => {
    console.log('Subscriber data:', data);
});

subject.next(3);

// output
// Subscriber data: 3

Subject: chỉ nhận data sau khi đã subscribe.

import * as Rx from "rxjs";

const subject = new Rx.BehaviorSubject(0);

subject.next(1);
subject.next(2);

subject.subscribe((data) => {
    console.log('Subscriber data:', data);
});

subject.next(3);

// output
// Subscriber data: 2
// Subscriber data: 3

BehavorSubject: Subscriber chỉ lấy được 2 giá trị trong khi Subject emit tới 3 giá trị, tức là chỉ giá trị cuối trước khi subscribe được lưu lại và emit cho subscriber.

import * as Rx from "rxjs";

const subject = new Rx.ReplaySubject(2);

subject.next(1)
subject.next(2)
subject.next(3)

// subscriber
subject.subscribe((data) => {
    console.log('Subscriber data:', data);
});

subject.next(4);

// Subscriber data: 2
// Subscriber data: 3
// Subscriber data: 4

ReplaySubject: tuy subscriber subscribe sau khi Subject đã emit 3 giá trị, tuy nhiên nó vẫn nhận được 3 giá trị, gồm 1 giá trị emit sau khi subscribe. Đó là bởi vì chúng ta đã cấu hình ReplaySubject lưu 2 giá trị trước để emit cho subscriber lúc bắt đầu đăng ký nhận dữ liệu.

Còn một khả năng nữa của ReplaySubject, đó là nó có thể lưu giá trị trước đó trong một khoảng thời gian cho trước. Sau thời gian này thì nó chỉ lưu lại 1 giá trị cũ mà thôi.

const subject = new Rx.ReplaySubject(2, 100);

Cuối cùng là AsyncSubject

import * as Rx from "rxjs";

const subject = new Rx.AsyncSubject();


subject.next(1)
subject.next(2)


subject.subscribe((data) => {
    console.log('Subscriber data:', data);
});

subject.next(3);
subject.complete();
subject.next(4))
// Subscriber data: 3

Chỉ có duy nhất 1 giá trị cuối cùng trước lúc gọi hàm complete() được nhận bởi Subscriber, dù cho Subject đã emit tới 4 lần.

Kết luận

BehaviorSubject, ReplaySubject AsyncSubject có thể dùng để truyền dữ liệu multicast giống như Subject bình thường, tuy nhiên chúng có thêm các tính năng sẽ hữu ích trong các tình huống khác nhau. Nắm được bản chất của các loại Subject này giúp chúng ta xử lý dữ liệu gọn gàng hơn.

Đam mê code via medium.com

One thought on “BehaviorSubject, ReplaySubject và AsyncSubject – khác nhau thế nào?

Leave a comment