组合多个无副作用的Rx动作

本文关键字:Rx 动作 无副作用 组合 | 更新日期: 2023-09-27 18:07:45

我如何添加(组成)更多的行动,例如,updateIndicators,而不是单一的行动,使信息流动没有副作用?

quote => 
{ 
    this.changeQuote(quote.S, quote.B, quote.A);
} // Add action here, e.g., UpdateIndicators()

var qu = Observable.FromEvent<ApiQuoteHandler, QuoteUpdate>(
                    emit => (_, s, b, a) => emit(new QuoteUpdate(s, b, a)),
                    handler => apiClient.QuoteUpdated += handler,
                    handler => apiClient.QuoteUpdated -= handler)
                                .Where(quote => (SymbolStrs.Contains(quote.S)))
                                .SubscribeOn(Scheduler.Default)
                                .Subscribe
                            (
                                quote => 
                                { 
                                    this.changeQuote(quote.S, quote.B, quote.A);
                                    // I could put updateIndicators in here, but it doesn't feel Rx composable like?
                                }
                            );
public void changeQuote(string symbol, double bid, double ask)
{
}
public void updateIndicators(string symbol, double bid, double ask)
{
}
// more actions here

组合多个无副作用的Rx动作

首先,很明显你的两个动作都只是的副作用

所以要么调用订阅2次:

var quoteUpdate = 
    Observable.FromEvent<ApiQuoteHandler, QuoteUpdate>(
        emit => (_, s, b, a) => emit(new QuoteUpdate(s, b, a)),
        handler => apiClient.QuoteUpdated += handler,
        handler => apiClient.QuoteUpdated -= handler)
    .Where(quote => (SymbolStrs.Contains(quote.S)));
var subscription1 =
    quoteUpdate
    .SubscribeOn(Scheduler.Default)
    .Subscribe (quote => this.changeQuote(quote.S, quote.B, quote.A));
var subscription2 =
    quoteUpdate
    .SubscribeOn(Scheduler.Default)
    .Subscribe (quote => this.updateIndicators(quote.S, quote.B, quote.A));

或者订阅一个Action,它只会一个接一个地调用另一个(正如你已经猜到的-不知道有什么问题):

public void DoBoth(string symbol, double bid, double ask)
{
    changeQuote(symbol,bid,ask);
    updateIndicators(symbol,bid,ask);
}
// ...
var subscription =
    quoteUpdate
    .SubscribeOn(Scheduler.Default)
    .Subscribe (quote => this.DoBoth(quote.S, quote.B, quote.A));

备注:

现在您只使用来自RX的WhereSubscribeOn,但是您有相当多的开销。如果你不想做更多,我建议只是处理事件本身与一个简单的if而不是.Where(当然调度到UI线程,如果你真的有)-这是更容易的方式,你不需要外部依赖于RX然后