没事不要用 rxjava 的create 操作符

来源:互联网 发布:毕向东java视频百度云 编辑:程序博客网 时间:2024/06/05 22:51

Curtis :没事不要使用Rxjava的create的操作符

Felicity : 为啥?

Curtis : 如果你不是很精通rxjava,或者理解rxjava的内部实现,可能会导致很多问题,例如背压和解除订阅

Felicity : 说的跟真的似的,你能举个例子么?

Curtis : 让我给你看一段代码

Observable     .create((Observable.OnSubscribe<Integer>) subscriber -> {         for (int i = 0; i < 500; i++) {             subscriber.onNext(i);         }         subscriber.onCompleted();     })     .subscribeOn(Schedulers.io())     .observeOn(Schedulers.computation())     .doOnNext(new Action1<Integer>() {         @Override         public void call(Integer integer) {             try {                 Thread.sleep(1000);             } catch (InterruptedException e) {                 e.printStackTrace();             }         }     })     .subscribe(new Subscriber<Integer>() {         @Override         public void onCompleted() {             System.out.println("onCompleted");         }         @Override         public void onError(Throwable e) {             e.printStackTrace();         }         @Override         public void onNext(Integer integer) {             System.out.println("onNext -> " + integer);         }     });

Curtis : 你看,运行结果是这样:

 onNext -> 0rx.exceptions.MissingBackpressureException    at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.onNext(OperatorObserveOn.java:160)    at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.onNext(OperatorSubscribeOn.java:74)    at main.java.com.pokercc.RxCreateDemo.lambda$main$0(RxCreateDemo.java:17)    at rx.Observable.unsafeSubscribe(Observable.java:10256)    at rx.internal.operators.OperatorSubscribeOn$SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)    at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)    at java.util.concurrent.FutureTask.run(FutureTask.java:266)    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at java.lang.Thread.run(Thread.java:745)

Curtis : 看懂了吗?Felicity
Felicity : 我懂了,就是用create操作符,直接操作Subscriber ,当在这种事件产生和事件消费速度差距相当大的时候,会报背压异常对吧。

Curtis : Bingo ! 我再给你看一段运行正常的代码

Observable        .range(0, 500)        .subscribeOn(Schedulers.io())        .observeOn(Schedulers.computation())        .doOnNext(new Action1<Integer>() {            @Override            public void call(Integer integer) {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        })        .subscribe(new Subscriber<Integer>() {            @Override            public void onCompleted() {                System.out.println("onCompleted");            }            @Override            public void onError(Throwable e) {                e.printStackTrace();            }            @Override            public void onNext(Integer integer) {                System.out.println("onNext -> " + integer);            }        });

Curtis : 看看我们这回输出是啥?

 onNext -> 0 onNext -> 1 ... onNext -> 499 onNext -> 500 onCompleted

Curtis : 这回走字了吧,使用Rxjava 提供的操作符就不会有这种问题了

Felicity : 真的耶,你是怎么发现这个问题的?

Curtis : 我当时在看rxjava的文档,发现了一个帖子,原文是这个http://blog.danlew.net/2015/07/23/deferring-observable-code-until-subscription-in-rxjava/

Felicty : 这都被你找到了,那你能告诉我原理吗?

Curtis : 下次吧,我现在要去找 Paul 看电影了

原创粉丝点击