日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > RxJava switchIfEmpty操作符實現Android檢查本地緩存邏輯判斷

RxJava switchIfEmpty操作符實現Android檢查本地緩存邏輯判斷

來源:程序員人生   發布時間:2016-12-12 15:32:05 閱讀次數:3329次

switchIfEmpty(Observable emptyObservable)操作符從字面意思上就很好理解,就是當為空的時候跳轉到emptyObservable。
那末如何理解當為空的時候. 下面將會使用實際案例解釋這個switchIfEmpty的使用方法。

業務需求

假設我們的app里有加載文章列表功能,要求加載的邏輯以下:加載文章的的時候,先從本地加載,如果本地存在就是用本地的數據,如果不存在從網絡獲得。

下面是業務代碼:

//從本地數據獲得文章列表 getArticlesObservable(pageIndex, pageSize, categoryId) //本地不存在,要求api .switchIfEmpty(articleApi.getArticlesByCategoryId(pageIndex + "", pageSize + "", categoryId + "") .compose(this.<RespArticlePaginate>handlerResult()) .flatMap(new Func1<RespArticlePaginate, Observable<RespArticlePaginate>>() { @Override public Observable<RespArticlePaginate> call(RespArticlePaginate respArticlePaginate) { if (respArticlePaginate != null && respArticlePaginate.getList() != null) { try { articleDao.insertOrReplaceInTx(respArticlePaginate.getList()); } catch (Exception e) { e.printStackTrace(); } } return Observable.just(respArticlePaginate); } })) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(createSubscriber(ID_ARTICLE_LIST)))

這里的 createSubscriber 封裝了Subscriber對成功、失敗的數據處理,然后統1把數據推給上1層,就不用每一個地方都寫下面相同的模板代碼了:

observable.subscribe(new Action1<RespArticlePaginate>() { @Override public void call(RespArticlePaginate respArticlePaginate) { //success data } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { // error data } })

那末createSubscriber是如何實現的,先看subscribe方法源碼 以下:

public final Subscription subscribe(final Action1<? super T> onNext, final Action1<Throwable> onError) { if (onNext == null) { throw new IllegalArgumentException("onNext can not be null"); } if (onError == null) { throw new IllegalArgumentException("onError can not be null"); } Action0 onCompleted = Actions.empty(); return subscribe(new ActionSubscriber<T>(onNext, onError, onCompleted)); }

很簡單,他是直接new了1個ActionSubscriber,然后把我們之前在代碼里寫的各個回調(onNext、onError、onComplete)當作參數傳遞進去。那末我們的createSubscriber也能夠摹擬它的實現:

/** * 處理結果(分發結果) 封裝 * * @param id 辨別業務類型 */ protected <T> ActionSubscriber<T> createSubscriber(final int id) { //由于我們只關心onNext和onError Action0 onCompleted = Actions.empty(); return new ActionSubscriber<T>(new Action1<T>() { @Override public void call(T t) { pushSuccessData(id, t); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { pushThrowable(id, throwable); } }, onCompleted); }

好了,言歸正傳,回到我們上面提到的需求。根據需求我們來分析下代碼:

getArticlesObservable方法用來從本地獲得文章列表,articleApi.getArticlesByCategoryId方法是用來當本地不存在的時候從網絡獲得。仿佛這些代碼可以實現了我們上面提到的需求了。而且很簡潔。

實踐是檢驗真諦的唯1標準,我們先運行下看看(本地環境是數據庫沒有文章列表)。

運行后,發現界面并沒有展現數據,通過debug返現,代碼履行了檢測本地緩存的邏輯,且本地找不到符合邏輯的數據,也就是說從本地找到的結果為空。但是沒有依照我們料想的是履行網絡要求。

先來看看查詢本地緩存的代碼是是甚么模樣。

Observable.create(new Observable.OnSubscribe<Object>() { @Override public void call(Subscriber<? super Object> subscriber) { try { List<Article> as = articleDao.queryBuilder() .where(ArticleDao.Properties.CategoryId.eq(categoryId)) .orderDesc(ArticleDao.Properties.Id) .offset((pageIndex - 1) * pageSize) .limit(pageSize).list(); if (as == null || as.isEmpty()) { subscriber.onNext(null); }else{ subscriber.onNext(as); } }catch (Exception e){ subscriber.onError(e); } subscriber.onCompleted(); } });

通過debug發現代碼走的邏輯是

if (as == null || as.isEmpty()) { subscriber.onNext(null); }

發送的是空,為何還是沒有走switchIfEmpty里的邏輯呢?肯定是我們用的姿式不對,先看看該該方法的說明:

/** * Returns an Observable that emits the items emitted by the source Observable or the items of an alternate * Observable if the source Observable is empty. * <p/> * <dl> * <dt><b>Scheduler:</b></dt> * <dd>{@code switchIfEmpty} does not operate by default on a particular {@link Scheduler}.</dd> * </dl> * * @param alternate * the alternate Observable to subscribe to if the source does not emit any items * @return an Observable that emits the items emitted by the source Observable or the items of an * alternate Observable if the source Observable is empty. * @since 1.1.0 */ public final Observable<T> switchIfEmpty(Observable<? extends T> alternate) { return lift(new OperatorSwitchIfEmpty<T>(alternate)); }

重點關注對參數Observable<? extends T> alternate的解釋:

the alternate Observable to subscribe to if the source does not emit any items

意思是如果原來的Observable沒有發射任何數據(emit any items),則使用alternate代替原來的Observable。

好,再看看我們的代碼邏輯:

if (as == null || as.isEmpty()) { subscriber.onNext(null); }

這段代碼不是沒有發射數據,而是發射了個空數據,也就是發射了null,所以這段代碼其實不是沒有發射任何數據,所以為何不走網絡要求的邏輯。
知道緣由就好解決了,加上個過濾就能夠解決問題了:

.filter(new Func1<RespArticlePaginate, Boolean>() { @Override public Boolean call(RespArticlePaginate respArticlePaginate) { return respArticlePaginate != null; } })

總結

1,通過switchIfEmpty可以做到1些邏輯判斷,固然實現類型的判斷本地緩存的,可以通過concat結合takeFirst操作符來實現,具體的可以看我之前的博客文章

2,上面通過Observable.create方式來包裝數據查詢,不是很優雅。下1篇博客介紹如何封裝RxJava,使得我們的代碼支持RxJava鏈式調用。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品一区久久久 | 黄色三级在线观看 | 日日干狠狠干 | 欧美亚洲激情视频 | 国产999精品久久久 日韩av成人在线 | 亚洲一区二区三区四区免费观看 | 日韩国产在线看 | 国产成人一区二区三区 | 欧美一区二区三区视频在线 | 欧美xxxx黑人又粗又长 | 在线观看国产一区 | 2018av在线| 亚洲午夜精品久久久久久浪潮 | 午夜精品影院 | 欧美成人一区二免费视频软件 | 一级肉体全黄裸片 | 日韩精品中文字幕一区二区三区 | 日日日操操操 | 99久久影视 | 久热中文 | 精品日韩在线 | 精品欧美一区二区精品久久 | 成人黄色片在线观看 | 久久成人一区二区 | 日本精品视频一区二区 | 老女人一级片 | 精品久久久久久久久久ntr影视 | 久久久久久久亚洲精品 | 日韩欧美在线一区二区三区 | 色综合色综合色综合色综合 | 黑人在线视频 | 日韩一区二区三区免费视频 | 91久久久久久 | 亚洲成人高清av | 黄色免费网站. | 日韩国产精品一区 | 日韩小视频 | 欧美精品导航 | 婷婷综合在线观看 | 成人性生交大片免费观看嘿嘿视频 | 波多野结衣av电影在线观看 |