2015-09-27 9 views
5

Sto cercando di imparare la libreria RxJS. Uno dei casi che non capisco è descritto in this jsfiddle (codice anche sotto).RxJS combineLatest: come ottenere l'emissione dopo aver modificato un solo valore?

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); 

Mi piacerebbe ottenere due emittenti nella registrazione "AB". Uno dalla modifica di B a "a" (A ha già il valore 0). Un altro da modificare A a 1.

Tuttavia, solo le modifiche che si verificano dopo un subscribe sembrano avere importanza (anche se A ha un valore e quindi il risultato combinato potrebbe essere calcolato).

Devo usare "osservabili caldi" per questo o qualche altro metodo rispetto allo .combineLatest?

Il mio problema nel codice reale (più grande di questo esempio) è che ho bisogno di fare inizializzazioni separate dopo gli abbonati, che taglia roba in due posti separati invece di avere i valori iniziali chiaramente in primo piano.

Grazie

risposta

9

penso che tu abbia frainteso come il lavoro Subjects. Subjectssono osservabili caldi. Non mantengono i valori, quindi se ricevono uno onNext senza iscritti, quel valore verrà perso nel mondo.

Quello che stai cercando è uno BehaviorSubject o lo ReplaySubject entrambi i quali conservano valori passati che li riemettono a nuovi abbonati. Nel primo caso si sempre costruisce con un valore iniziale

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

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

in quest'ultimo si imposta il numero di valori da riprodurre per ogni abbonamento

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

riscrittura tuo esempio potrebbe essere:

In un'altra nota, realizzando ovviamente che questo è tutto nuovo per voi, nella maggior parte dei casi non è necessario utilizzare uno Subject direttamente come generalmente mea ns che stai cercando di ingannare Rx nella sicurezza dei tuoi noti paradigmi. Dovresti chiederti da dove vengono i tuoi dati? Come viene creato? Se fai queste domande a sufficienza, seguendo la tua catena di eventi fino all'origine, 9 volte su 10 scoprirai che probabilmente c'è un wrapper Observable.

+0

Ottima risposta Paul, grazie! BehaviorSubject funziona davvero per me, e apprezzo molto l'ultimo paragrafo che hai scritto. Scommetto che hai ragione. I miei valori provengono da trascina mouse; andrà oltre con la documentazione Rx per capirlo più pienamente. – akauppi

+1

@akauppi yep mouse trascinamenti sono ovviamente eventi osservabili, controlla [daEvent] (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromevent.md). Nella pienezza dei tempi in cui hai più esperienza Rx, puoi imparare a mettere insieme tutto questo dalla sorgente di eventi del mouse osservabili fino al risultato finale osservabile usando solo operatori Rx senza mai dover lavorare direttamente con ' '. – Brandon

+0

@Brandon sto imparando Rx adesso. :) Alla fine renderà pubblico il mio esperimento che combina SVG con RxJs (penso che leghi gli oggetti insieme). – akauppi

Problemi correlati