在Rx中Run和Do的区别是什么?

本文关键字:区别 是什么 Do Rx Run | 更新日期: 2023-09-27 18:19:22

旧版本的响应式扩展为IEnumerable提供了Run和Do扩展方法。他们似乎在做完全相同的事情,我不确定有什么不同。

我问这个问题是因为我正在升级一些旧代码,Do已经被转移到Ix(这还不是一个稳定的版本),看起来Run已经被ForEach取代了。

在Rx中Run和Do的区别是什么?

Do指定执行时会产生一些副作用,并返回带有副作用的序列。

Run枚举序列,并返回void。

可以这样想:"标记"具有副作用的序列。这些副作用只有在枚举序列时才会发生。Do返回带有副作用的新序列。

// Example of .Do
var elements = new[] { 1, 2, 3 };
var elementsWithSideEffects = elements.Do(e => MessageBox.Show(e)); // No Message Boxes shown yet!
elementsWithSideEffects.Run(); // 3 message boxes shown
另一方面,

Run枚举序列:Run(),或者可选地附加副作用,然后枚举序列:Run(action)

// Example of .Run with its own side effects:
var elements = new[] { 1, 2, 3 };
elements.Run(e => MessageBox.Show(e)); // 3 Message Boxes shown.

您可以将Do视为"Peek",因为它对每个值/错误/完成执行副作用,但不能更改它们的值,因为传递的lambda都返回void。它类似于Subscribe,但它不会打破单子("链"),因为它返回IObservable<T>Do常用于日志记录。

Run基本上是Subscribe的阻塞版本,这意味着执行不会继续超过该行,直到OnComplete/OnError被调用。

把Do想象成一个安培计:你切断电路(查询操作符链),并为电流(通过查询操作符的值)连接一个仪表(操作委托)。对于流经电路(查询)的每一个电子(值),仪表(动作)都要做功。注意,电路(查询)仍然未通电(惰性)。直到您插入电池(运行foreach循环),电流(值)才开始流动。打开电路(运行查询)的一种简单方法是使用一个蓄电池(ForEach操作符)。

Do的行为就像其他LINQ操作符,如Select或Where——如果你只是使用它,什么也不会发生,你必须要foreach才能发生一些事情。Run/ForEach/Subscribe的行为类似于foreach语句,它立即执行。

如果你不是100%清楚什么时候使用每一个,避免使用Do,只使用ForEach/Run。