简单介绍一下业务逻辑:获取字符串,若是获取失败进行10次重试,超出10次未成功视为失败。javascript
模拟获取字符串场景java
class MsgTool { int count; String getMsg() throws Exception { count++; LogUtils.d("execute getMsg count : " + count); if (count == 15) { return "getMsg"; } else { throw new Exception("exception getMsg"); } } }
Java代码实现逻辑(实现方式不少种,这里不是重点)ide
public void testMain() { LogUtils.d("result : " + getSyncMsg()); } private String getSyncMsg() { MsgTool msgTool = new MsgTool(); String result = null; boolean isSuccess = false; int count = 0; while ((count < 10) && !isSuccess) { try { result = msgTool.getMsg(); isSuccess = true; } catch (Exception e) { count++; } } return result; }
23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 1 23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 2 23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 3 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 4 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 5 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 6 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 7 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 8 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 9 23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 10 23:33:14.909 32364-32377/? D/LogUtils: result : null
针对上述业务逻辑改成RxJava实现,使用操做符retry
可实现this
public void testMain() { getSyncMsg().subscribe(getSubscriber()); } private Observable<String> getSyncMsg() { MsgTool msgTool = new MsgTool(); Observable<String> o = Observable.create(subscriber -> { try { subscriber.onNext(msgTool.getMsg()); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }); return o.retry(10); } private Subscriber<Object> getSubscriber() { return new Subscriber<Object>() { @Override public void onCompleted() { LogUtils.d("onCompleted"); } @Override public void onError(Throwable e) { LogUtils.d("onError : " + e.toString()); } @Override public void onNext(Object o) { LogUtils.d("onNext : " + o); } }; }
23:45:43.761 3285-3307/? D/LogUtils: execute getMsg count : 1 23:45:43.762 3285-3307/? D/LogUtils: execute getMsg count : 2 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 3 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 4 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 5 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 6 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 7 23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 8 23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 9 23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 10 23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 11 23:45:43.765 3285-3307/? D/LogUtils: onError : java.lang.Exception: exception getMsg
下面咱们增长一个业务逻辑,每次重试延迟一秒种。此功能不作Java代码实现(使用定时器、Android系统下使用Handler等),而用RxJava代码实现,虽然看着很迷糊,可是慢慢品味就会发觉它的魅力所在。code
public void testMain() { getSyncMsg().subscribe(getSubscriber()); } private Observable<String> getSyncMsg() { MsgTool msg = new MsgTool(); Observable<String> o = Observable.create(subscriber -> { try { subscriber.onNext(msg.getMsg()); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }); return o.retryWhen(this::delayRetry); } //此方法就是魅力的所在 private Observable<Object> delayRetry(Observable<? extends Throwable> o) { return o.zipWith(Observable.range(1, 10), //控制10次之内 (throwable, integer) -> { if (integer == 10) { //若是是最后一次,结合的结果是异常。 return throwable; } else { return integer; } }) .flatMap(object -> Observable.create(subscriber -> { //转换retryWhey发射的数据 if (object instanceof Throwable) { subscriber.onError((Throwable) object); } else { subscriber.onNext(o); subscriber.onCompleted(); } }).delay(1, TimeUnit.SECONDS)); //延迟一秒发射 } private Subscriber<Object> getSubscriber() { return new Subscriber<Object>() { @Override public void onCompleted() { LogUtils.d("onCompleted"); } @Override public void onError(Throwable e) { LogUtils.d("onError : " + e.toString()); } @Override public void onNext(Object o) { LogUtils.d("onNext : " + o); } }; }
00:36:57.271 19355-19372/? D/LogUtils: onStart 00:36:57.297 19355-19372/? D/LogUtils: execute getMsg count : 1 00:36:58.305 19355-19377/? D/LogUtils: execute getMsg count : 2 00:36:59.306 19355-19404/? D/LogUtils: execute getMsg count : 3 00:37:00.307 19355-19375/? D/LogUtils: execute getMsg count : 4 00:37:01.308 19355-19376/? D/LogUtils: execute getMsg count : 5 00:37:02.308 19355-19377/? D/LogUtils: execute getMsg count : 6 00:37:03.309 19355-19404/? D/LogUtils: execute getMsg count : 7 00:37:04.309 19355-19375/? D/LogUtils: execute getMsg count : 8 00:37:05.310 19355-19376/? D/LogUtils: execute getMsg count : 9 00:37:06.311 19355-19377/? D/LogUtils: execute getMsg count : 10 00:37:06.320 19355-19377/? D/LogUtils: onError : java.lang.Exception: exception getMsg