15

当某些条件发生变化时,我有两个流信号。我需要一个 Observable ,它会true所有条件转变时触发truefalse他们中的任何一个转身时false。如果某些条件是false并且另一个更改false我不需要引发事件。

这是我的做法:

// Introducing current states
private bool cond1 = false;
private bool cond2 = false;

void MyHandlingMethod(IObservable<bool> c1, IObservable<bool> c2)
{
    c1.Subscribe(b => _state1 = b);
    c2.Subscribe(b => _state2 = b);

    var c3 = c1.Merge(c2).Select(_ => _cond1 && _cond2);

    c3.Subscribe(b => /* some action goes here /*);
    // ...
}

我想知道这是否是解决我的问题的正确方法以及是否有任何陷阱。例如,由于 rx 的异步特性,c3 订阅在 c1 和 c2 之前触发。

4

3 回答 3

18

不需要保持状态:

c3 = c1.CombineLatest(c2, (a, b) => a && b).DistinctUntilChanged()
于 2013-03-13T14:35:41.527 回答
2

老实说,我可能会采用这种CombineLatest方法,但为了接触 Rx 框架中未触及的部分......

虽然不是完美契合,但您可以使用Observable.When//模式Observable.AndObservable.Then

var firstStream = new Subject<bool>();
var secondStream = new Subject<bool>();
var thirdStream = new Subject<bool>();
var fourthStream = new Subject<bool>();

var query = Observable.When(firstStream
        .And(secondStream)
        .And(thirdStream)
        .And(fourthStream)
        .Then((v1,v2,v3,v4) => v1 & v2 & v3 & v4));

using(query.Subscribe(Console.WriteLine))
{
    firstStream.OnNext(true);
    secondStream.OnNext(true);
    thirdStream.OnNext(true);
    // output stream will fire after this statement
    fourthStream.OnNext(true);
    Console.ReadLine();
}

这种方法的一个好处是,只有当所有流都具有根据Then子句组合的数据时,您才创建输出事件 - 它也读起来相当不错。也就是说,它对您的用例有一个严重的失败:您必须在每个传入流上都有数据才能触发输出流:

using(query.Subscribe(Console.WriteLine))
{
    firstStream.OnNext(true);
    secondStream.OnNext(true);
    thirdStream.OnNext(true);
    // output stream will fire after this statement
    fourthStream.OnNext(true);

    // this WON'T raise false on the output!
    firstStream.OnNext(false);
    secondStream.OnNext(false);
    thirdStream.OnNext(false);
    // output stream will fire false after this statement
    fourthStream.OnNext(false);
    Console.ReadLine();
}
于 2013-03-13T15:32:58.530 回答
0

像 JerKimball 一样,我将建议使用 Joins(现在何时):

IObservable<bool> cond1 = new [] { false, true, true, false, false }.ToObservable();
IObservable<bool> cond2 = new [] { true, true, false, false, true }.ToObservable();
Func<bool, bool> isFalse = (x) => x == false;
Func<bool, bool> isTrue = (x) => x == true;
var trueC1s = cond1.Where(isTrue);
var falseC1s = cond1.Where(isFalse);
var trueC2s = cond2.Where(isTrue);
var falseC2s = cond2.Where(isFalse);
var trues = trueC1s.And(trueC2s).Then((_, __) => true);
var falses = trueC1s.And(falseC2s).Then((_, __) => false);
var falses2 = falseC1s.And(trueC2s).Then((_, __) => false);
var falses3 = falseC1s.And(falseC2s).Then((_, __) => false);
Observable.When(trues, falses, falses2, falses3).Dump();

但是,当有很多 Observable 时,它​​确实会变得有点混乱。

于 2013-03-13T15:50:31.837 回答