Reactive Programming with RxJava-Chapter7:Test and Troubleshooting(1)

来源:互联网 发布:数据分析师 泉州 编辑:程序博客网 时间:2024/05/21 11:09

Error Handling

The Reactive Manifesto enumerates four traits that reactive systems should embrace
- responsive
- resilient
- elastic
- message driven

Where Are My Exceptions

In RxJava,failures are just another type of notification.Every Observable is a sequence of events of type T optionally followed by completion or error notification.

Subscribe() only listening for values and not errors is often a bad sign and possibly missed errors.Even if you do not except any exceptions to happen (which is rarely the case),at least place error logging that plugs into your logging framework.

It is advised to explicitly propagate exceptions via subscriber.onError() if possible.Even better,use fromCallable()

Declarative try-catch Replacement

Replacing errors with a fixed result using onErrorReturn()

onErrorReturn() is a fluent and very pleasant to read alternative to a try-catch block that returns fixed result in the catch statement know from imperative style;

Lazily computing fallback value using onErrorResumeNext()

There are two possible scenarios here:
- The primary way of generating a stream of data failed (onError() event,so we switch to a secondaty source that is just as good,but for some reason we treate it as backup)
- In the presence of a failure,we would like to replace real data with some less expensive,more stable,maybe stale information.

The onErrorResumeNext() operator basically replaces error notification with another stream.If you subscribe to an Observable guarded with onErrorResumeNext() in case of failure,RxJava transparently switches from main Observable to the fallback one,specified as an argument.

Timing out When Events Do Not Occur

simplest use case for timeout():timeout(long,TimeUnit)
timeout(long,TimeUnit)

This is quite common in real-life systems: the initial element of the response has relatively high latency as a result of establishing the connection,SSL handshake,query optimization,or whatever the server is doing.But subsequent responses are either readily available or easily retrievable,so latency between them is much lower;
timeout(Func0,Func1)

Similar in behavior to onErrorResumeNext();
timeout(long,TimeUnit,Observable)

Retrying After Failures

The onError notification is terminal;no other event can ever appear in such stream.

Attention
If your Observable is cached or otherwise guaranteed to always return the same sequence of elements,retry() will not work:

    risky().cached().retry()  //BROKEN

To overcome this issue,you can delay the creation of Observable even futher by using defer()

    Observable        .defer(() -> risky())        .retry()

Retrying by using delay and limited attempts

retryWhen(Func1)
retryWhen(Func1)

Attention
The retryWhen operator is similar to retry but decides whether or not to resubscribe to and mirror the source Observable by passing the Throwable from the onError notification to a function that generates a second Observable, and observes its result to determine what to do. If that result is an emitted item, retryWhen resubscribes to and mirrors the source and the process repeats; if that result is an onError notification, retryWhen passes this notification on to its observers and terminates.

Observable.create((Subscriber<? super String> s) -> {      System.out.println("subscribing");      s.onError(new RuntimeException("always fails"));  }).retryWhen(attempts -> {      return attempts.zipWith(Observable.range(1, 3), (n, i) -> i).flatMap(i -> {          System.out.println("delay retry by " + i + " second(s)");          return Observable.timer(i, TimeUnit.SECONDS);      });  }).toBlocking().forEach(System.out::println);

result:

subscribingdelay retry by 1 second(s)subscribingdelay retry by 2 second(s)subscribingdelay retry by 3 second(s)subscribing

Another example:

static final int ATTEMPTS = 11;//....retryWhen(attempts -> attempts        .zipWith(Observable.range(1,ATTEMPTS) , (err,attempt) ->                attempt < ATTEMPTS ?                        Observable.timer(1,SECONDS) :                        Observable.error(err))        .flatMap(x -> x))

最后,安利一款自己写的基于MVP的Android开发框架
https://github.com/sxenon/Pure
欢迎大家拍砖,如果觉得好,麻烦多多star

0 0