学习Reactive Extensions(Rx) --- 笔记1

代码片段:

Observable.Interval(TimeSpan.FromSeconds(0.25))//创建了一个每0.25秒发出递增数字的Observable
.Do(x =>
{
//Do操作符的作用,它允许在不修改观察者的情况下添加副作用,比如打印日志
Console.WriteLine(x);//用Do操作处理的OnNext事件:打印每个值
})
.Subscribe();//添加订阅
//调用Subscribe()实际上是创建了一个空的观察者,只是启动了数据流。
//这里的订阅者是隐式创建的,由Rx框架生成的观察者实例,这个观察者会接收事件,
//但因为Subscribe没有参数,所以除了Do中的操作,不会有其他处理
//Subscribe()即使没有参数,也会触发Observable开始发射数据,因为订阅本身就是启动数据流的信号

运行效果如下图,数字一直不断打印:

**解释说明 **

1、Observable.Interval(TimeSpan.FromSeconds(0.25))

这会创建一个Observable(可观察序列),每隔0.25秒自动发出一个从0开始递增的long型数字值,

相当于创建了一个每秒触发4次的计数器。

2、Do(x=>{Console.WriteLine(x);})

Do操作符用于在数据流中添加“副作用”————不修改数据流,只执行额外操作。

这里的作用是将每个发出的数值x通过Console.WriteLine打印到控制台。

注意:

如果缺少订阅,那么Do操作就不会执行。

在Rx中,Observable需要被订阅(Subscribe)才会激活数据流。

在Rx(Reactive Extensions)中,.Subscribe()的订阅者(订阅者)是由Rx框架隐式创建的观察者(Observer)。

当调用 .Subscribe() 时,Rx 会自动生成一个默认的观察者实例(即使没有显式传递任何回调函数)。这个观察者的作用是:

(1)、启动数据流:触发 Observable 开始发射数据。

(2)、处理事件:接收 OnNext、OnError、OnCompleted 事件(如果没有自定义处理,默认会忽略这些事件)。

.Subscribe(); // 隐式创建了一个空的观察者

Do和Subscribe的关系

Do 操作符:

作用:在数据流中添加“副作用”(例如打印日志、记录状态)。

不修改数据流:它不会改变事件的传递,只是“偷看”数据流。

与订阅无关:Do 不会启动数据流,只是定义了一个中间操作。

Subscribe 方法:

作用:触发订阅行为,激活 Observable 并开始接收事件。

必需调用:没有 Subscribe,Observable 永远不会开始发射数据。

.Do(x => Console.WriteLine(x)) // 定义副作用(打印)
.Subscribe(); // 启动数据流

即使 **Subscribe() 没有参数,Do **中定义的副作用仍会执行,因为 Do 是在数据流中插入的操作,与订阅者无关。

如果要显示传递一个观察者,最初的代码等价于:

var observable = Observable.Interval(TimeSpan.FromSeconds(0.25))
.Do(x => Console.WriteLine(x));

observable.Subscribe(
x => { /* 默认空实现(不处理 OnNext) / },
ex => { /
默认空实现(不处理 OnError) / },
() => { /
默认空实现(不处理 OnCompleted) */ }
);

此时:

Do 负责打印 OnNext 事件。

Subscribe 的默认空观察者仅激活数据流,不做其他操作。

总结

Observable.Interval :创建数据流(不发射数据,直到被订阅)。

Do :定义副作用(例如打印),但不启动数据流。

Subscribe() :隐式创建观察者,启动数据流,使 Observable 开始工作。

常见问题

1、为什么需要 Subscribe 才能启动数据流?

Rx 的设计遵循“冷观察者”(Cold Observable)模式:只有在订阅后,Observable 才会开始生产数据。

这种设计避免资源浪费(例如无用的计时器)。

2、如果忘记调用 Subscribe 会怎样?

数据流永远不会激活,Do 中的代码也不会执行。例如原始代码缺少 Subscribe,就不会有任何输出。

3、是否必须传递参数给 Subscribe?

不是。如果不需要处理 OnNext/OnError/OnCompleted,可以调用无参的 Subscribe()。此时 Rx 会用默认观察者激活数据流。

posted @ 2025-04-17 22:03  长松入霄汉远望不盈尺  阅读(81)  评论(0)    收藏  举报