簡單介紹一下業務邏輯:獲取字符串,若是獲取失敗進行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