如何协调可观察序列,使一个序列只在另一个序列完成时开始?
我有3种不同类型的可观察物:
var obs1 = ...
var obs2 = ...
var obs2 = ...
我想做:
obs1.Subscribe( () => obs2.Subscribe( ()=> obs3.Subscribe( () => /* Hide Progress */ )));
但是这个代码真的很难看。有接线员吗?我尝试使用And()
扩展方法,但我不确定这是否是正确的方法。
好吧,如果你不介意引入TPL,你可以使用await
:
await obs1;
await obs2;
await obs3;
如果您想在使用等待的同时观察每个的值,只需添加Do
:
await obs1.Do(t1 => ...);
await obs2.Do(t2 => ...);
await obs3.Do(t3 => ...);
这能满足您的要求吗?
obs1
.Concat(obs2)
.Concat(obs3)
.Subscribe(x => /* ... */ );
显然,这只适用于冷可观察器。如果您的obs2
&obs3
很热,您可能会错过值。
Enigmativity是正确的,尽管您只需要同时使用Select
。
obs1.Select(t => new { t, (U)null, (V)null })
.Concat(
obs2.Select(u => new { (T)null, u, (V)null }))
.Concat(
obs3.Select(v => new { (T)null, (U)null, v }))
.Subscribe(either =>
{
if (either.t != null) Observe(either.t);
else if (either.u != null) Observe(either.u);
else if (either.v != null) Observe(either.v);
else { throw new Exception("Oops."); }
})
另请参阅我的一篇相关博客文章:T 的力量
如果你只对观察obs3感兴趣,你可能想这样写:
obs1.TakeLast(1)
.SelectMany(x => obs2)
.TakeLast(1)
.SelectMany(y => obs3)
.Subscribe(z => ... ); // z is the same type of obs3's data type
我们从obs1中获取最后一项,当它到达时,我们使用SelectMany订阅并输出obs2。然后,我们重复从返回的Observable中获取最后一个项,当最后一个项目到达时,我们再次使用SelectMany订阅并输出obs3。之后,您可以订阅返回的Observable,并根据自己的意愿处理obs3。