Rx Java:Observable在订阅者请求项目之前发出项目

时间:2017-06-11 17:36:45

标签: rx-java observable

在下面的例子中,我希望我的订阅者最初从observable请求两个项目,然后每5秒再请求两个:

public class RxJavaExample {

public static void main(String[] args) {
  Observable.range(1, 6)
      .flatMap(testData -> {
        System.out.println("next item");
        return Observable.just(testData);
      }, 1)
    .toBlocking()
    .subscribe(new Subscriber<Integer>() {

      public void onStart() {
        System.out.println("requesting\n\n");
        request(2);
        Observable.interval(5, SECONDS)
            .subscribe(
                x -> {
                  System.out.println("requesting\n\n");
                  request(2);
                }); 
      }

      @Override
      public void onCompleted() {
        System.out.println("done");
      }

      @Override
      public void onError(Throwable e) {
        System.err.println(e);
      }

      @Override
      public void onNext(Integer testData) {
        System.out.println("OnNext");
      }
    });
 }
}

在这种情况下,我希望输出为:

requesting


next item
next item
OnNext
OnNext
requesting


next item
next item
OnNext
OnNext
requesting


next item
next item
OnNext
OnNext
done

但这是我得到的实际输出:

  next item
  requesting


  next item
  next item
  OnNext
  OnNext
  requesting


  next item
  OnNext
  OnNext
  next item
  requesting


  next item
  OnNext
  OnNext
  done

在订阅者请求任何内容之前,似乎Observable仍会发出一个项目。为什么会发生这种情况,是否有办法确保Observable只在我的订阅者请求后才发出项目?

我的例子非常人为,因为我可以使用map代替flatMap,它会给我我想要的行为但是对于我的实际用例,我需要使用{{1} }。

1 个答案:

答案 0 :(得分:1)

这是因为flatMap()运算符,它根据请求的并发级别向生产者(源range() Observable)添加请求,在您要求并发性为1的情况下,所以{{ 1}}将在范围flatMap上调用request(1),因此生产者将在订阅者请求任何内容之前生成单个项目。

注意,这里有2个缓冲区,虽然Observable已经在订阅者之前请求了项目,但它只会导致range()生成项目,但是你不会在{{{{{{ 1}},意思是你的onNext序列符合预期,只是flatMap()以不同的方式生成项目。

BTW,在默认情况下onNext()意味着没有并发限制,它会请求无限项,在这种情况下,所有项目都将立即生成,而不仅仅是一个项目。