RxJS:我将如何“手动”更新Observable?


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'),但似乎实际上没有用,这被调用给观察者,这似乎不正确。观察者应该是对数据流做出反应的事物,而不是对其进行更改,对吗?

我只是不了解观察者/可观察的关系吗?


请看一下以阐明您的想法(您已经缺少对Reactive编程的介绍):gist.github.com/staltz/868e7e9bc2a7b8c1f754。这里也有很多资源,您可以从中提高理解:github.com/Reactive-Extensions/RxJS#resources
user3743222 2015年

我检查了第一个,似乎是一个坚实的资源。第二个列表很不错,在上面找到了aaronstacy.com/writings/reactive-programming-and-mvc,它帮助我发现了解决问题的Rx.Subject。那谢谢啦!一旦编写了更多应用程序,我将发布解决方案,只是想对它进行一些测试。
LiamD 2015年

呵呵,非常感谢您提出这个问题,我要问的是同样的问题,并记着相同的代码示例:-)
arturh 2016年

Answers:


154

在RX中,Observer和Observable是不同的实体。观察者订阅了一个Observable。一个Observable通过调用观察者的方法向其观察者发射项目。如果您需要在范围之外调用观察者方法,则Observable.create()可以使用Subject,Subject是同时充当观察者和Observable的代理。

您可以这样:

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
LiamD 2015年

34

我相信Observable.create()不是将观察者作为回调参数,而是将其作为发射器。因此,如果要向Observable添加新值,请尝试以下方法:

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更容易,在同一对象中提供Observable和Observer,但是并不完全相同,因为当Observable仅将数据发送到最后一个订阅的观察者时,Subject允许您将多个观察者订阅到同一可观察对象,因此请有意识地使用它。如果您想尝试一下,这里是一个JsBin


RxJS手册中某处记录了覆盖发射器属性的可能性吗?
Tomas

在这种情况下,emitter只会next()为预订最后一个的观察者提供新的值。更好的方法是将所有emitters 收集到数组中,并遍历所有s和它们next的值
Eric Gopak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.