Flowable Subscriber:request()方法实际上做了什么?

时间:2017-11-10 09:06:30

标签: android rx-java rx-java2

任何人都可以告诉request()中的DisposableSubscriber方法做什么以及何时使用?我们仅在您使用Flowable创建自己的Flowable.create时使用它?官方文件说

  
    

请求(长n):     如果已经通过onSubscribe设置了Subscription,则从上游请求指定的金额。

  

但我不明白这是什么意思。试试我做了如下样本

private Flowable<Long> streamOfNums() {
    return Flowable.create(e -> {
        for (int i = 0; i < 500; i++) {
            e.onNext((long) i);
            Log.d(TAG, "produced "+i);
        }
    }, BackpressureStrategy.BUFFER);
}

一样消费它
        streamOfNums()
            .subscribeOn(Schedulers.io())
            .subscribeWith(new DisposableSubscriber<Long>() {

                @Override
                protected void onStart() {
                    super.onStart();
                    Log.d(TAG, "onStart: ");
                }

                @Override
                public void onNext(Long aLong) {
                    Log.d(TAG, "onNext: ");
                    try {
                        Log.d(TAG, "consuming data :"+aLong);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    request(4);
                }

                @Override
                public void onError(Throwable t) {

                }

                @Override
                public void onComplete() {

                }
            });

我能看到的是每次发射器在给定延迟(2000 ms)后产生数字。我给了request(4),但即使没有它,它也会以完全相同的方式工作。 任何人都可以解释request做什么以及何时使用它。它可以用于分页场景吗?

1 个答案:

答案 0 :(得分:1)

request允许消费者告诉生产者要生产多少元素。默认情况下,DisposableSubscriber在其Long.MAX_VALUE方法中请求onStart(),在这种情况下,进一步的request()调用无效。

很少需要在这样的最终消费者中实际调用request,但是当你的最终消费者充当异步边界时,你可以使用它来避免缓冲区溢出:

ExecutorService executor = Executors.newSingleThreadedExecutor();

Flowable.range(1, 500)
    .doOnNext(v -> Log.d("produced: " + v))
    .subscribeOn(Schedulers.io())
    .subscribe(new DisposableSubscriber<Long>() {
            @Override protected void onStart() {
                Log.d(TAG, "onStart: "); // <----- no super.onStart() here!
                request(1);
            }
            @Override public void onNext(Long aLong) {
                executor.execute(() -> {
                    Log.d(TAG, "onNext: ");
                    try {
                        Log.d(TAG, "consuming data :"+aLong);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    request(1);
                });
            }
            @Override public void onError(Throwable t) {
                 executor.execute(() -> t.printStackTrace());
            }

            @Override public void onComplete() {
                 executor.execute(() -> Log.d("onComplete"));
            }
        });

Thread.sleep(100_000);
executor.shutdown();