如何对可观察量进行排序?

时间:2014-10-07 02:03:46

标签: c# system.reactive reactive-programming

如何协调可观察序列,以便只在另一个完成后才开始?

我有3种不同类型的观察:

var obs1 = ...
var obs2 = ...
var obs2 = ...

我想这样做:

obs1.Subscribe( () => obs2.Subscribe( ()=> obs3.Subscribe( () => /* Hide Progress */ )));

但这段代码真的很难看。有一些经营者这样做吗?我尝试使用And()扩展方法,但我不确定这是否正确。

4 个答案:

答案 0 :(得分:1)

好吧,如果你不介意介绍TPL,你可以使用await

await obs1;
await obs2;
await obs3;

如果您想在仍然使用等待时观察每个值,只需添加Do

await obs1.Do(t1 => ...);
await obs2.Do(t2 => ...);
await obs3.Do(t3 => ...);

答案 1 :(得分:0)

这样做你想要的吗?

obs1
    .Concat(obs2)
    .Concat(obs3)
    .Subscribe(x => /* ... */ );

显然这只适用于冷观察者。如果你的obs2& obs3很热,你可能会错过价值观。

答案 2 :(得分:0)

虽然您只需要使用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."); }
     })

另见我的相关博文:The Power of T

答案 3 :(得分:0)

如果您只对观察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。