学习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  青云Zeo  阅读(31)  评论(0)    收藏  举报