界面上有两个Button分别为+和-操作,点击+按钮则+1,点击-按钮则-1,最终的结果显示在一个Label中。
这样的一个需求使用经典事件模型只需要维护一个内部变量,两个按钮的Click事件分别对变量做加1或减1的操作即可。
Rx作为一种函数式编程模型讲求immutable-不可变性,即不使用变量来维护内部状态。
这个例子使用了IObservable<T>的”谓词”来对事件流做了一些操作。
下面就让我们来看看IObservable<T>中常用的“谓词”
四、IObservable<T>中的谓词
IObservable<T>的灵感来源于LINQ,所以很多操作也跟LINQ中的操作差不多,例如Where、First、Last、Single、Max、Any。
还有一些“谓词”则是新出现的,例如上面提到的”Merge”、“Scan”等,为了理解这些“谓词”的含义,我们请出一个神器RxSandbox。
1、Merge操作,从下面的图中我们可以清晰的看出Merge操作将三个事件流中的事件合并在了同一个时间轴上。
2、Where操作则是根据指定的条件筛选出事件。
有了这个工具我们可以更加方便的了解这些“谓词”的用途。
五、IObservable<T>的创建
Observable类提供了很多静态方法用来创建IObservable<T>,之前的例子我们都使用FromEventPattern方法来将事件转化为IObservable<T>,接下来再看看别的方法。
Range方法可以产生一个指定范围内的IObservable<T>
Observable.Range(1, 10) .Subscribe(x => Console.WriteLine(x.ToString()));Interval方法可以每隔一定时间产生一个IObservable<T>:
Observable.Interval(TimeSpan.FromSeconds(1)) .Subscribe(x => Console.WriteLine(x.ToString()));Subscribe方法有一个重载,可以分别对Observable发生异常和Observable完成定义一个回调函数。
Observable.Range(1, 10) .Subscribe(x => Console.WriteLine(x.ToString()), e => Console.WriteLine("Error" + e.Message), () => Console.WriteLine("Completed"));还可以将IEnumerable<T>转化为IObservable<T>类型:
Enumerable.Range(1, 10).ToObservable() .Subscribe(x => Console.WriteLine(x.ToString()));也可以将IObservable<T>转化为IEnumerable<T>
var list= Observable.Range(1, 10).ToEnumerable();六、其他Rx资源
除了.net中的Rx.net,其他语言也纷纷推出了自己的Rx框架。