RxJS: Як би я "вручну" оновив спостережуване?


139

Я думаю, що я повинен нерозуміти щось фундаментальне, тому що, на мою думку, це повинно бути найосновнішим випадком спостережуваного, але все життя мого я не можу зрозуміти, як це зробити з документів.

В основному, я хочу, щоб це зробити:

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

Але мені не вдалося знайти такий спосіб push. Я використовую це для обробника кліків, і я знаю, що вони мають Observable.fromEventдля цього, але я намагаюся використовувати його з React, і я скоріше зможу просто оновити потік даних у зворотній зв'язок, замість того, щоб використовувати зовсім інший система обробки подій. Тому я хочу цього:

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

Найближче до мене було використання observer.onNext('foo'), але це, здається, насправді не працює, і це викликається спостерігачем, що не здається правильним. Спостерігачем має бути те, що реагує на потік даних, не змінюючи його, правда?

Я просто не розумію відносини спостерігач / спостережуваний?


Погляньте на це, щоб уточнити свою ідею (Вступ до Реактивного програмування ви пропустили): gist.github.com/staltz/868e7e9bc2a7b8c1f754 . Тут також є купа ресурсів, за допомогою яких ви можете поліпшити своє розуміння: github.com/Reactive-Extensions/RxJS#resources
user3743222

Я перевірив перше, схоже, це надійний ресурс. Другий - чудовий список, в ньому я знайшов aaronstacy.com/writings/reactive-programming-and-mvc, який допоміг мені відкрити Rx.Subject, який вирішує мою проблему. Тож дякую! Після того, як я написав трохи більше програми, я опублікую своє рішення, просто хочу трохи перевірити його.
ЛіамD

Хе-х, дуже дякую, що ви задали це запитання, я збирався задати це саме запитання з таким самим зразком коду на увазі :-)
arturh

Відповіді:


154

У RX спостерігач і спостережуваний є різними сутностями. Спостерігач підписується на спостережуване. Спостерігаючий випромінює елементи своїх спостерігачів, викликаючи методи спостерігачів. Якщо вам потрібно викликати методи спостереження за межами Observable.create()вашої області, ви можете використовувати Subject, який є проксі-сервером, який виступає одночасно як спостерігач і спостерігається.

Ви можете зробити так:

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

Ви можете знайти більше інформації про теми тут:


1
Це насправді саме те, що я завершив, роблячи! Я продовжував працювати над цим, щоб побачити, чи зможу знайти кращий спосіб зробити те, що мені потрібно зробити, але це, безумовно, життєздатне рішення. Я вперше побачив це в цій статті: aaronstacy.com/writings/reactive-programming-and-mvc .
ЛіамД

34

Я вважаю Observable.create(), що спостерігач сприймає не парам, а емітер. Тож, якщо ви хочете додати нове значення до свого " Спостережуваного", спробуйте це:

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"

Так, Subject полегшує, надаючи спостерігаючим і спостерігачем один і той же об'єкт, але це не точно так само, оскільки Subject дозволяє передплачувати декілька спостерігачів на один і той же обсерваторій, коли спостережна надсилає дані лише останньому підписаному спостерігачеві, тому використовуйте їх свідомо . Ось JsBin, якщо ви хочете повозитися з ним.


Можливість перезапис властивостей випромінювача задокументована десь у посібниках RxJS?
Томаш

У цьому випадку emitterз’являться лише next()нові значення для спостерігача, який підписався останнім. Кращим підходом було б зібрати всі emitterмасиви в масив і перебрати через них усі nextзначення і значення для кожного з них
Ерік Гопак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.