【问题标题】:Why/How should I use Publish without Connect?为什么/我应该在没有 Connect 的情况下使用 Publish?
【发布时间】:2018-12-13 00:28:48
【问题描述】:

为什么/如何在没有ConnectRefCount 呼叫关注的情况下使用.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);

pairspairs2 有何不同:

var pairs2 = source
    .Skip(1)
    .Zip(source, (newer, older) => (older, newer));

【问题讨论】:

    标签: system.reactive rx.net


    【解决方案1】:

    Publish&lt;TSource, TResult&gt;(Func&lt;IObservable&lt;TSource, IObservable&lt;TResult&gt;&gt; selector) 重载的文档很少。 Lee Campbell 没有在introtorx.com 中介绍它。它不返回IConnectableObservable,这是大多数人与Publish 关联的,因此不需要或支持ConnectRefCount 调用。

    Publish 的这种形式基本上是一种防御性编码形式,可以防止源 observable 中可能出现的副作用。它订阅源一次,然后可以通过传入的参数安全地“多播”所有消息。如果你看问题代码,只有一次提到了source,两次提到了_source_source 这里是安全多播的 observable,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;
    });
    

    ...您会发现“Print me once”用pairs(正确)打印一次,用pairs2 打印两次。当您的 observable 包装诸如 DB 查询、Web 请求、网络调用、文件读取和其他您希望只发生一次而不是多次发生的副作用代码时,这种效果具有类似的含义。

    TL;DR:如果您有一个 observable 查询引用了 observable 两次,最好将该 observable 包装在 Publish 调用中。

    【讨论】:

    • 呜呜呜。我正要投票,但后来我看到了return System.Reactive.Disposables.Disposable.Empty;。这有点像用剪刀跑步——这很危险,如果你只是用它来说明,那么你应该有一个很大的免责声明。总的来说,我很喜欢你对 Rx 的回答。
    • 谢谢。我不同意你对那个特定的反模式过敏。这不是很好,但简单的Create 示例非常需要它。我写这个是因为我在其他问题中反复解释它。也许写一个问答,为什么你讨厌Create + Disposable.Empty
    • 感谢您的回复。你能告诉我在哪里写一个问答吗?我想你的意思不是在这里作为一个问题?另外,请给我一些.Create 需要Disposable.Empty 的示例?
    • 这就是我的意思。写一个问题,然后勾选复选框以添加答案。这就是我在这里所做的。
    • 至于没有Disposable.Empty.Create... 像这样的情况,您希望在订阅时产生副作用(无论出于何种原因),然后是一个没有副作用的常规旧可观察对象终止。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 2011-05-20
    • 2012-12-18
    • 1970-01-01
    • 2021-04-07
    相关资源
    最近更新 更多