自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

理解RxJava中的Single和Completable

開發(fā) 后端
但是你仔細(xì)思考下,你真的需要每次都知道這 3 個(gè)事件嗎?實(shí)際上,在大多數(shù)情況下并不需要。ReactiveX 文檔中講述的基本都是關(guān)于連續(xù)的事件流,因此我們經(jīng)常忘記通常我們關(guān)心的只是監(jiān)聽單一事件或者只監(jiān)聽 completed or failed 事件。

在大多數(shù) RxJava 示例代碼和教程中出現(xiàn)最為頻繁的一個(gè)類 —— Observable,它是產(chǎn)生響應(yīng)式編程魔力的關(guān)鍵。它的用法很簡單,只需要跟蹤 3 個(gè)事件 —— onNext,onErroronCompleted就可以應(yīng)用上百個(gè)操作符來實(shí)現(xiàn)自己的表達(dá)式。那么為什么你還需要了解其他東西?

但是你仔細(xì)思考下,你真的需要每次都知道這 3 個(gè)事件嗎?實(shí)際上,在大多數(shù)情況下并不需要。ReactiveX 文檔中講述的基本都是關(guān)于連續(xù)的事件流,因此我們經(jīng)常忘記通常我們關(guān)心的只是監(jiān)聽單一事件或者只監(jiān)聽 completed or failed 事件。

RxJava

在這種情況下我們應(yīng)該考慮用 RxJava 的兩個(gè)絕妙的設(shè)計(jì) —— Single<T> 和 Completable,在分析兩者之前,讓我們先看看他們應(yīng)用場(chǎng)景的示例。

本文中所有代碼都是基于 RxJava 2.x ,不是 1.x 版本。如果你還沒升級(jí) RxJava 到***的 2.x 版本, 強(qiáng)烈建議你馬上升級(jí)。

Single

在 Android 中使用 RxJava 最常見的場(chǎng)景就是網(wǎng)絡(luò)請(qǐng)求,你可能使用 Retrofit 作為項(xiàng)目的 Http client。假設(shè)你有一個(gè) GET HTTP 請(qǐng)求返回一些數(shù)據(jù),同時(shí)使用 RxJavaAdapter 你大概會(huì)這么寫:

public interface APIClient {

    @GET("my/api/path")
    Observable<MyData> getMyData();
}

上面的代碼沒什么問題,當(dāng)調(diào)用它時(shí):

apiClient.getMyData()
    .subscribe(new Consumer<MyData myData>() {
        @Override
        public void accept(MyData myData) throws Exception {
            // handle data fetched successfully
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception{
            // handle error event
        }
    }, new Action() {
        @Override
        public void run() throws Exception {
            // handle on complete event
        }
    });

仔細(xì)思考下,其實(shí)這個(gè)網(wǎng)絡(luò)請(qǐng)求并不是一個(gè)連續(xù)事件流,你只會(huì)發(fā)起一次 Get 請(qǐng)求返回?cái)?shù)據(jù)并且只收到一個(gè)事件。我們都知道這種情況下 onComplete 會(huì)緊跟著 onNext 被調(diào)用,那為什么不把它們合二為一呢?

在上面這種情況下為了更清楚的體現(xiàn)請(qǐng)求的意圖,應(yīng)該用Single<MyData>替換 Observable。從官方文檔中對(duì) Single 的說明可以發(fā)現(xiàn)為什么它是最恰當(dāng)?shù)倪x擇:A Single is something like an Observable, but instead of emitting a series of values — anywhere from none at all to an infinite number — it always either emits one value or an error notification。所以修改后 API client 是這樣的:

public interface APIClient {

    @GET("my/api/path")
    Single<MyData> getMyData();
}

同時(shí)請(qǐng)求的調(diào)用也可以簡化:

apiClient.getMyData()
    .subscribe(new Consumer<MyData>() {
        @Override
        public void accept(MyData myData) throws Exception {
            // handle data fetched successfully and API call completed
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception{
            // handle error event
        }
    });

最值得高興的是 Single 基本上實(shí)現(xiàn)了 Observable 所有的操作符 —— mapflatMap、filterzip等,如果你發(fā)現(xiàn)需要用到一個(gè) Observable 的操作符而 Single 并不支持,你可以用toObservable操作符把Single<T>轉(zhuǎn)換為Observable<T>。

apiClient.getMyData()
    .toObservable()
    // This is an Observable<MyData> now

如果你有 Observable 表現(xiàn)地像 Single 一樣,也可以通過singleOrError操作符轉(zhuǎn)換為 Single。

Completable

繼續(xù)討論 Retrofit 的例子,再看看另外一種常用場(chǎng)景 —— 通過 PUT 請(qǐng)求更新數(shù)據(jù)。我們修改了 MyData 類型對(duì)象的一些屬性,把它發(fā)送到服務(wù)器更新服務(wù)器數(shù)據(jù)庫。大部分服務(wù)器 API 設(shè)計(jì)都是成功后返回更新后的對(duì)象,所以你的 API client 的實(shí)現(xiàn)是:

public interface APIClient {

    @PUT("my/api/updatepath")
    Observable<MyData> updateMyData(@Body MyData data);
}

同樣的,跟之前的例子類似,應(yīng)該這樣調(diào)用:

apiClient.updateMyData(myUpdatedData)
    .subscribe(new Consumer<MyData myData>() {
        @Override
        public void accept(MyData myData) throws Exception {
            // handle data fetched successfully and API call completed
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception{
            // handle error event
        }
    }, new Action() {
        @Override
        public void run() throws Exception {
            // handle completion - what we actually care about
        }
    });

你可能會(huì)說這里我們可以同樣用 Single 來簡化代碼,是的沒錯(cuò)。在這種情況下我們?nèi)匀恍枰?MyData 結(jié)果,確定?服務(wù)器返回給我們更新后的數(shù)據(jù)是良好的設(shè)計(jì),當(dāng)時(shí)實(shí)際上僅僅是返回給我們之前發(fā)送給它的對(duì)象。我們真正需要的只是更新成功了,這意味著,我只關(guān)心 onComplete 事件。

這也是引入Completable的原因,官方文檔對(duì)它的描述是:Represents a computation without any value but only indication for completion or exception。使用 Completable 時(shí)我們忽略 onNext 事件,只處理 onComplete 和 onError 事件,API client 改寫為:

public interface APIClient {

    @PUT("my/api/updatepath")
    Completable updateMyData(@Body MyData data);
}

調(diào)用為:

apiClient.updateMyData(myUpdatedData)
    .subscribe(new Action() {
        @Override
        public void run() throws Exception {
            // handle completion
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception{
            // handle error
        }
    });

Completable 本質(zhì)上來說和 Observable 與 Single 不一樣,因?yàn)樗话l(fā)射數(shù)據(jù)。因此 Completable 的操作符也有所區(qū)別,最常用的是andThen。在這個(gè)操作符中你可以傳任何Observable、Single、Flowable、Maybe或者其他Completable,它們會(huì)在原來的 Completable 結(jié)束后執(zhí)行。例如。你想執(zhí)行一些其他操作(Single):

apiClient.updateMyData(myUpdatedData)
    .andThen(performOtherOperation()) // a Single<OtherResult>
    .subscribe(new Consumer<OtherResult>() {
        @Override
        public void accept(OtherResult result) throws Exception {
            // handle otherResult
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception{
            // handle error
        }
    });

跟 Single 不同的是 RxJava 不允許直接把 Observable 轉(zhuǎn)換為 Completable,因?yàn)闆]辦法知道一個(gè) Observable 什么時(shí)候 complete。但是你可以把 Single 轉(zhuǎn)換為 Completable,因?yàn)?Single 保證 onComplete 會(huì)被調(diào)用,這個(gè)操作符是toCompletable。

希望通過這篇簡短的對(duì) Single 和 Completable 的介紹能讓你理解這兩個(gè)概念從而寫出更簡潔的代碼。

責(zé)任編輯:張燕妮 來源: johnnyshieh
相關(guān)推薦

2017-01-19 13:34:54

AndroidRxJava線程模型

2011-03-22 09:49:15

JavaScript

2009-06-25 14:26:07

JSPJavaBeanServlet

2023-03-29 10:19:44

異步編程AsyncPromise

2016-04-13 11:05:02

C++引用匿名對(duì)象

2009-06-12 18:54:46

異常程序開發(fā)

2023-10-27 11:27:14

Go函數(shù)

2023-10-31 10:51:56

MySQLMVCC并發(fā)性

2024-03-08 15:29:01

DockerUIDGID

2013-06-05 10:11:20

索引器C#

2017-06-05 11:03:07

Linuxshutdown命令

2019-04-12 14:26:17

Linux命令文件

2021-10-08 07:53:01

Go 尋址元素

2018-09-20 16:10:48

CookiesSession前端

2021-07-30 15:06:05

鴻蒙HarmonyOS應(yīng)用

2014-11-11 15:25:30

PHPWeb

2020-08-31 07:19:57

MonoFlux Reactor

2021-06-15 16:11:51

Linux手冊(cè)頁

2016-11-17 15:35:51

RxJava操作Subscriber

2019-12-10 09:53:27

LinuxCacheBuffer
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)