当某些条件发生变化时,我有两个流信号。我需要一个Observable,当所有条件转为true
时,它会触发true
。当其中任何一个转为false
时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之前触发。
答案 0 :(得分:12)
没有必要保持状态:
c3 = c1.CombineLatest(c2, (a, b) => a && b).DistinctUntilChanged()
答案 1 :(得分:2)
老实说,我可能会采用CombineLatest
方法,但为了触及Rx框架中有些未被触及的部分......
虽然不是完美契合,但您可以使用Observable.When
/ Observable.And
/ Observable.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();
}
答案 2 :(得分: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时,它确实有点乱。