为什么这些 Rx 序列乱序?

Why are these Rx sequences out of order?

假设我写

var gen = Observable.Range(1, 3)
  .SelectMany(x => Observable.Range(1, x));

生成的序列如预期的那样1 1 2 1 2 3。但是现在如果我写

var gen = Observable.Range(1, 4)
  .SelectMany(x => Observable.Range(1, x));

现在生成的序列是 1 1 2 1 2 1 3 2 3 4 而不是人们期望的 1 1 2 1 2 3 1 2 3 4。这是为什么? SelectMany() 是否进行某种多线程合并?

Observable.Range() 本身将始终按顺序生成其事件。但是 SelectMany() 不会等待前一个可观察对象完成后再开始下一个。这意味着随着序列越来越长,重叠也会越来越多,因为下一个序列将在前一个序列完成之前开始,依此类推。

如果您试图让输出是连续的,那么您将需要使用不同的方法来展平序列,例如 Concat().

例如:

var gen = Observable.Range(1, 4)
  .Select(x => Observable.Range(1, x)).Concat();

输出:1,1,2,1,2,3,1,2,3,4

SelectMany() 不同,Concat() 会在开始下一个序列之前等待每个序列完成。