组合几个没有副作用的Rx动作

时间:2015-08-13 04:04:24

标签: c# system.reactive

如何添加(撰写)更多操作,例如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

1 个答案:

答案 0 :(得分:0)

首先,显然你的两个行动都只是副作用

所以只需要拨打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));

或订阅一个只会一个接一个地调用的动作(正如您已经猜到的那样 - 不要看到它有什么问题):

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的外部依赖