2014-10-07 89 views
0

你如何协调可观测序列,以便只有当另一个完成时才开始?如何排序observables?

我有3个观察到的不同的类型:

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

我想做的事:

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

但这种代码实在是太丑了。有没有一些运营商来做到这一点?我尝试使用And()扩展方法,但我不确定这是否正确。

回答

1

好吧,如果你不介意引入TPL,你可以用await

await obs1; 
await obs2; 
await obs3; 

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

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

这是做你想做的吗?

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

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

+0

不,对于concat工作,observables必须是相同类型(返回相同类型)。我的观察结果是不同的类型。我需要的更像是一个.ContinueWith() – 2014-10-07 02:29:00

0

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."); } 
    }) 

参见我的一个相关的博客帖子:The Power of T

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。