2015-09-27 17 views
5

Tôi đang cố gắng tìm hiểu thư viện RxJS. Một trong những trường hợp tôi không hoàn toàn hiểu được được mô tả trong this jsfiddle (mã cũng dưới đây).RxJS combinedLatest: làm thế nào để phát ra sau chỉ một giá trị thay đổi?

var A= new Rx.Subject(); 
var B= new Rx.Subject(); 

A.onNext(0);  

// '.combineLatest' needs all the dependency Observables to get emitted, before its combined signal is emitted. 
// 
// How to have a combined signal emitted when any of the dependencies change (using earlier given values for the rest)? 
//  
A.combineLatest(B, function (a,b) { return a+b; }) 
.subscribe(function (v) { console.log("AB: "+ v); }); 

B.onNext("a"); 
A.onNext(1); 

Tôi muốn nhận hai lần phát ra bản ghi "AB". Một từ thay đổi B thành "a" (A đã có giá trị 0). Một thay đổi khác từ thay đổi A thành 1.

Tuy nhiên, chỉ những thay đổi xảy ra sau khi đăng ký có vẻ quan trọng (mặc dù A có giá trị và do đó kết quả kết hợp có thể được tính toán).

Tôi có nên sử dụng "quan sát nóng" cho điều này hoặc một số phương pháp khác ngoài .combineLatest không?

Vấn đề của tôi trong mã thực tế (lớn hơn mẫu này) là tôi cần tạo các bản khởi tạo riêng sau khi đăng ký, cắt nội dung ở hai vị trí riêng biệt thay vì có giá trị ban đầu rõ ràng lên phía trước.

Cảm ơn

Trả lời

9

Tôi nghĩ bạn đã hiểu sai cách hoạt động của Subjects. Subjects Quan sát nóng. Họ không giữ giá trị, vì vậy nếu họ nhận được onNext không có người đăng ký nào thì giá trị đó sẽ bị mất cho thế giới.

Những gì bạn đang tìm kiếm là BehaviorSubject hoặc ReplaySubject cả hai đều giữ giá trị trong quá khứ để phát lại chúng cho người đăng ký mới. Trong trường hợp trước đây bạn luôn luôn xây dựng nó với một giá trị ban đầu

//All subscribers will receive 0 
var subject = new Rx.BehaviorSubject(0); 

//All subscribers will receive 1 
//Including all future subscribers 
subject.onNext(1); 

trong sau này bạn thiết lập số lượng các giá trị để được thực hiện lại cho mỗi thuê bao

var subject = new Rx.ReplaySubject(1); 
//All new subscribers will receive 0 until the subject receives its 
//next onNext call 
subject.onNext(0); 

Viết lại ví dụ của bạn nó có thể là:

var A= new Rx.BehaviorSubject(0); 
var B= new Rx.Subject();  

// '.combineLatest' needs all the dependency Observables to get emitted, before its combined signal is emitted. 
// 
// How to have a combined signal emitted when any of the dependencies change (using earlier given values for the rest)? 
//  
A.combineLatest(B, function (a,b) { return a+b; }) 
.subscribe(function (v) { console.log("AB: "+ v); }); 

B.onNext("a"); 
A.onNext(1); 

//AB: 0a 
//AB: 1a 

Lưu ý khác, việc nhận ra tất nhiên điều này hoàn toàn mới đối với bạn, trong hầu hết các trường hợp, bạn không cần sử dụng trực tiếp Subject vì nó thường là mea ns rằng bạn đang cố gắng để wrangle Rx vào sự an toàn của các mô hình đã biết của bạn. Bạn nên tự hỏi mình, dữ liệu của bạn đến từ đâu? Nó được tạo ra như thế nào? Nếu bạn hỏi những câu hỏi đó đủ, theo chuỗi sự kiện của bạn sao lưu vào nguồn, 9 trong số 10 lần bạn sẽ thấy rằng có lẽ là một wrapper Observable cho nó.

+0

Câu trả lời rất hay Paul, cảm ơn! BehaviorSubject thực sự làm việc cho tôi, và tôi đánh giá rất nhiều đoạn cuối cùng bạn đã viết. Tôi cá là bạn nói đúng. Giá trị của tôi là từ việc kéo chuột; sẽ đi xa hơn với tài liệu Rx để hiểu nó đầy đủ hơn. – akauppi

+1

@akauppi yep kéo chuột là tất nhiên các sự kiện quan sát được, hãy xem [fromEvent] (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromevent.md). Khi bạn đã trải nghiệm Rx nhiều hơn, bạn có thể học cách kết hợp tất cả những điều này với nhau từ nguồn của các sự kiện chuột quan sát được tới kết quả quan sát cuối cùng của bạn bằng cách sử dụng các toán tử Rx mà không cần phải làm việc trực tiếp với 'Subjects '. – Brandon

+0

@Brandon Tôi đang học Rx ngay bây giờ. :) Cuối cùng sẽ công khai thử nghiệm của tôi kết hợp SVG với RxJs (suy nghĩ buộc các đối tượng lại với nhau). – akauppi

Các vấn đề liên quan