RxJS: Come potrei aggiornare manualmente un osservabile?


139

Penso di dover fraintendere qualcosa di fondamentale, perché nella mia mente questo dovrebbe essere il caso più elementare per un osservabile, ma per la mia vita non riesco a capire come farlo dai documenti.

Fondamentalmente, voglio essere in grado di fare questo:

// create a dummy observable, which I would update manually
var eventObservable = rx.Observable.create(function(observer){});
var observer = eventObservable.subscribe(
   function(x){
     console.log('next: ' + x);
   }
...
var my_function = function(){
  eventObservable.push('foo'); 
  //'push' adds an event to the datastream, the observer gets it and prints 
  // next: foo
}

Ma non sono stato in grado di trovare un metodo simile push. Sto usando questo per un gestore di clic, e so che ce l'hanno Observable.fromEventper quello, ma sto provando a usarlo con React e preferirei semplicemente aggiornare il flusso di dati in un callback, invece di usare un completamente diverso sistema di gestione degli eventi. Quindi in pratica voglio questo:

$( "#target" ).click(function(e) {
  eventObservable.push(e.target.text()); 
});

Il più vicino che ho ottenuto è stato usare observer.onNext('foo'), ma non sembrava funzionare davvero e questo è stato chiamato dall'osservatore, il che non sembra giusto. L'osservatore dovrebbe essere la cosa che reagisce al flusso di dati, senza cambiarlo, giusto?

Semplicemente non capisco la relazione osservatore / osservabile?


Dai un'occhiata a questo per chiarire la tua idea (L'introduzione alla Programmazione Reattiva che ti sei perso): gist.github.com/staltz/868e7e9bc2a7b8c1f754 . Anche qui ci sono un sacco di risorse dalle quali puoi migliorare la tua comprensione: github.com/Reactive-Extensions/RxJS#resources
user3743222

Avevo verificato il primo, sembra una risorsa solida. La seconda è una grande lista, su di essa ho trovato aaronstacy.com/writings/reactive-programming-and-mvc che mi ha aiutato a scoprire Rx.Subject, che risolve il mio problema. Quindi grazie! Una volta che avrò scritto un po 'più di app, pubblicherò la mia soluzione, voglio solo lottare per testarla un po'.
LiamD,

Hehe, grazie mille per aver posto questa domanda, stavo per fare la stessa domanda con in mente lo stesso esempio di codice :-)
arturh

Risposte:


154

In RX, Observer e Observable sono entità distinte. Un osservatore si abbona a un osservabile. Un osservabile emette oggetti per i suoi osservatori chiamando i metodi degli osservatori. Se devi chiamare i metodi di osservatore al di fuori del tuo ambito di applicazione Observable.create(), puoi usare un Soggetto, che è un proxy che agisce come osservatore e Osservabile allo stesso tempo.

Puoi fare così:

var eventStream = new Rx.Subject();

var subscription = eventStream.subscribe(
   function (x) {
        console.log('Next: ' + x);
    },
    function (err) {
        console.log('Error: ' + err);
    },
    function () {
        console.log('Completed');
    });

var my_function = function() {
  eventStream.next('foo'); 
}

Puoi trovare maggiori informazioni sugli argomenti qui:


1
Questo è esattamente quello che ho finito per fare! Ho continuato a lavorarci per vedere se potevo trovare un modo migliore per fare quello che dovevo fare, ma questa è sicuramente una soluzione praticabile. L'ho visto per primo in questo articolo: aaronstacy.com/writings/reactive-programming-and-mvc .
LiamD,

34

Credo Observable.create()che non prenda un osservatore come parametro di callback ma un emettitore. Quindi, se vuoi aggiungere un nuovo valore al tuo Osservabile, prova questo:

var emitter;
var observable = Rx.Observable.create(e => emitter = e);
var observer = {
  next: function(next) {
    console.log(next);
  },
  error: function(error) {
    console.log(error);
  },
  complete: function() {
    console.log("done");
  }
}
observable.subscribe(observer);
emitter.next('foo');
emitter.next('bar');
emitter.next('baz');
emitter.complete();

//console output
//"foo"
//"bar"
//"baz"
//"done"

Sì, il Soggetto rende più semplice, fornendo Osservabile e Osservatore nello stesso oggetto, ma non è esattamente lo stesso, poiché Soggetto ti consente di iscrivere più osservatori allo stesso osservabile quando un osservabile invia solo dati all'ultimo osservatore sottoscritto, quindi usalo consapevolmente . Ecco un JsBin se vuoi armeggiare con esso.


la possibilità di sovrascrivere la proprietà dell'emettitore è documentata da qualche parte nei manuali RxJS?
Tomas,

In questo caso emittersaranno solo i next()nuovi valori per l'osservatore che ha sottoscritto l'ultimo. Un approccio migliore sarebbe quello di raccogliere tutti emitteri messaggi in un array e di scorrere tutti e nextil valore su ognuno di essi
Eric Gopak,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.