Khi nào sử dụng asObservable () trong rxjs?


84

Tôi đang tự hỏi việc sử dụng asObservable:

Theo tài liệu:

Một chuỗi có thể quan sát được ẩn danh tính của chuỗi nguồn.

Nhưng tại sao bạn cần phải ẩn trình tự?

Câu trả lời:


187

Khi nào sử dụng Subject.prototype.asObservable ()

Mục đích của việc này là để ngăn rò rỉ "phía quan sát viên" của Đối tượng ra khỏi API. Về cơ bản để ngăn chặn sự trừu tượng bị rò rỉ khi bạn không muốn mọi người có thể "tiếp theo" vào kết quả có thể quan sát được.

Thí dụ

(LƯU Ý: Đây thực sự không phải là cách bạn nên tạo một nguồn dữ liệu như thế này thành một nguồn có thể quan sát được, thay vào đó bạn nên sử dụng hàm new Observabletạo, Xem bên dưới).

const myAPI = {
  getData: () => {
    const subject = new Subject();
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subject.next({ type: 'message', data });
    source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data });
    return subject.asObservable();
  }
};

Bây giờ khi ai đó nhận được kết quả có thể quan sát được từ myAPI.getData()họ, họ không thể đánh nextgiá cao kết quả:

const result = myAPI.getData();
result.next('LOL hax!'); // throws an error because `next` doesn't exist

Bạn thường nên sử dụng new Observable(), mặc dù

Trong ví dụ trên, chúng ta có thể đang tạo ra thứ gì đó mà chúng ta không cố ý. Đối với một, getData()không phải là lười biếng như hầu hết các thiết bị quan sát, nó sẽ tạo ra nguồn dữ liệu cơ bản SomeWeirdDataSource(và có lẽ là một số tác dụng phụ) ngay lập tức. Điều này cũng có nghĩa là nếu bạn retryhoặc repeatkết quả có thể quan sát được, nó sẽ không hoạt động như bạn nghĩ.

Tốt hơn bạn nên gói gọn việc tạo nguồn dữ liệu trong phạm vi có thể quan sát được của bạn như sau:

const myAPI = {
  getData: () => return new Observable(subscriber => {
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subscriber.next({ type: 'message', data });
    source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data });
    return () => {
      // Even better, now we can tear down the data source for cancellation!
      source.destroy();
    };
  });
}

Với đoạn mã trên, bất kỳ hành vi nào, bao gồm cả việc làm cho nó trở nên "không lười biếng" có thể được tạo trên đầu trang có thể quan sát được bằng cách sử dụng các toán tử hiện có của RxJS.


3
TX Ben ... đang theo dõi nội dung của bạn ... tx vì tất cả sự hỗ trợ tuyệt vời trên RX
Born2net

3
@Shardul ... bạn đăng ký để có kết quả:result.subscribe(value => doSomething(value))
Ben Lesh

2
@BenTaliadoros Có, mỗi lần bạn return subject.asObservable();sẽ là một lần quan sát mới. Bạn sẽ có một biến thành viên Chủ đề duy nhất và onMessage / onOtherMessage sẽ được khai báo trong một điều kiện hoặc khi khởi tạo (không phải mọi cuộc gọi). Tôi đã sử dụng cách tiếp cận đó, pipe( filter() )dựa trên một tham số được cung cấp cho getData()hàm. The
Drenai

5
@BenLesh, trong mẫu mã thứ hai của bạn được subjectcho là subscriber?
Florin D

1
Tôi cũng muốn xác minh ở đây: các subject.nextdòng có nên không subscriber. Ngoài ra, "nếu bạn thử lại hoặc lặp lại kết quả có thể quan sát được, nó sẽ không hoạt động như bạn nghĩ." Bạn có thể cụ thể hơn không? Ý của bạn new SomeWeirdDataSource()là sẽ xảy ra mỗi khi getDatađược gọi và điều đó bằng cách gói nó vào trong, new Observablebạn thực hiện việc khởi tạo đó đợi cho đến khi đăng ký. Tôi đoán tôi không biết khi nào bạn sẽ gọi getDatamà không có một .subscribevì vậy tôi đang thiếu giá trị ở đó. Cuối cùng, bạn thấy trước điều gì xảy ra để xảy ra "phá hủy nguồn dữ liệu"? Cảm ơn.
1252748

7

A Subjectcó thể hoạt động như một observervà một observable.

An Obervablecó 2 phương pháp.

  • đăng ký
  • hủy đăng ký

Bất cứ khi nào bạn đăng ký một observable, bạn sẽ nhận được một observertrong đó có các phương pháp tiếp theo , lỗihoàn chỉnh trên đó.

Bạn cần phải ẩn trình tự vì bạn không muốn nguồn phát trực tiếp có sẵn công khai trong mọi thành phần. Bạn có thể tham khảo @BenLeshví dụ của tương tự.

Tái bút: Khi tôi lần đầu tiên sử dụng Reactive Javascript, tôi không thể hiểu được asObservable. Bởi vì tôi phải chắc chắn rằng tôi hiểu những điều cơ bản rõ ràng và sau đó bắt đầu asObservable. :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.