web-dev-qa-db-fra.com

RxJS: Comment pourrais-je mettre à jour "manuellement" un observable?

Je pense que je dois mal comprendre quelque chose de fondamental, parce que, dans mon esprit, ceci devrait être le cas le plus fondamental pour un observable, mais pour la vie de moi, je ne peux pas comprendre comment le faire à partir de la documentation.

En gros, je veux pouvoir faire ceci:

// 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
}

Mais je n'ai pas été capable de trouver une méthode comme Push. J'utilise ceci pour un gestionnaire de clics, et je sais qu'ils ont Observable.fromEvent pour cela, mais j'essaie de l'utiliser avec React et je préférerais pouvoir simplement mettre à jour le flux de données dans un rappel, au lieu d'utiliser un système de gestion des événements complètement différent. Donc, fondamentalement, je veux ceci:

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

Le plus proche que j'ai eu utilisait observer.onNext('foo'), mais cela n'a pas semblé réellement fonctionner et cela a appelé l'observateur, ce qui ne semble pas correct. L'observateur doit être ce qui réagit au flux de données sans le modifier, non?

Est-ce que je ne comprends pas la relation observateur/observable?

120
LiamD

Dans RX, Observer et Observable sont des entités distinctes. Un observateur s'abonne à un observable. Un observable émet des éléments à ses observateurs en appelant ses méthodes. Si vous devez appeler les méthodes observateur en dehors du champ d'application de Observable.create(), vous pouvez utiliser un sujet, qui est un proxy qui agit à la fois comme observateur et comme observable.

Vous pouvez faire comme ça:

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

Vous pouvez trouver plus d'informations sur les sujets ici:

137
luisgabriel

Je crois que Observable.create() ne prend pas un observateur comme paramètre de rappel, mais un émetteur. Donc, si vous voulez ajouter une nouvelle valeur à votre Observable , essayez ceci à la place:

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"

Oui Subject facilite les choses en fournissant Observable et Observateur dans le même objet, mais ce n'est pas exactement le même, car Subject vous permet d'inscrire plusieurs observateurs au même observable lorsqu'un observable envoie uniquement des données au dernier observateur auquel vous êtes abonné. Utilisez-le donc consciemment. . Voici un JsBin si vous voulez le bricoler.

30
theFreedomBanana