为什么/如何在没有Connect
或RefCount
调用的情况下使用.Publish()
?它有什么作用?示例代码:
var source = new Subject<int>();
var pairs = source.Publish(_source => _source
.Skip(1)
.Zip(_source, (newer, older) => (older, newer))
);
pairs.Subscribe(p => Console.WriteLine(p));
source.OnNext(1);
source.OnNext(2);
source.OnNext(3);
source.OnNext(4);
pairs
与这里的pairs2
有何不同:
var pairs2 = source
.Skip(1)
.Zip(source, (newer, older) => (older, newer));
Publish<TSource, TResult>(Func<IObservable<TSource, IObservable<TResult>> selector)
重载的文档很少。李·坎贝尔(Lee Campbell)没有在 introtorx.com 中涵盖它。它不返回IConnectableObservable
,这是大多数人与Publish
相关联的,因此不需要或支持Connect
或RefCount
调用。
这种形式的Publish
基本上是一种防御性编码形式,可以防止可观察源中可能的副作用。它订阅一次源,然后可以通过传入参数安全地"多播"所有消息。如果你看一下问题代码,只有一次提到source
,两次提到_source
。_source
这里是安全的多播可观察对象,source
是不安全的
。在上面的例子中,源是一个简单的Subject
,所以它并不是真的不安全,因此Publish
没有效果。但是,如果要将source
替换为以下内容:
var source = Observable.Create<int>(o =>
{
Console.WriteLine("Print me once");
o.OnNext(1);
o.OnNext(2);
o.OnNext(3);
o.OnNext(4);
return System.Reactive.Disposables.Disposable.Empty;
});
。您会发现"打印我一次"用pairs
打印一次(正确),用pairs2
打印两次。这种效果具有类似的含义,其中可观察量包装了数据库查询、Web 请求、网络调用、文件读取和其他副作用代码等内容,您希望只发生一次而不是多次。
TL;DR:如果你有一个可观察查询两次引用一个可观察量,最好将该可观察量包装在Publish
调用中。