RxJava主题

In this tutorial, we’ll be discussing Subjects in RxJava. We won’t be covering the basics of RxJava. If you are new to RxJava, do read this tutorial before proceeding ahead.

在本教程中,我们将在RxJava要讨论的主题 。 我们不会介绍RxJava的基础知识。 如果您不熟悉RxJava,请先阅读教程,然后再继续。

什么是主题? (What is a Subject?)

We know Observables and Observers. Observables emit data. Observers listen to those emissions by subscribing with the help of Subscribers.

我们知道可观察者和观察者。 可观察对象发出数据。 观察者通过在订户的帮助下进行订阅来收听这些辐射。

Subjects can emit and subscribe to the data. They have the implementations of Observables as well as Observers.

受试者可以发出并订阅数据。 它们具有Observables和Observers的实现。

A Subject has the same operators that an Observable has.
They can multicast too. This means all the Observers subscribed to it will receive the same emissions from the point of subscription.
This prevents doing duplicate operations for multiple subscribers.

主题具有与可观察对象相同的运算符。
他们也可以多播。 这意味着所有订阅的观察者将从订阅点接收相同的发射。
这样可以防止对多个订户进行重复操作。

Where is a Subject used?

在哪里使用主题?

Subjects are commonly used when you need to observe some data and then later can emit that data to other observers.

当您需要观察一些数据然后稍后可以将该数据发送给其他观察者时,通常使用主题。

Let’s look at an example with and without Subject. We’ll see how Subject saves us from redundant operations.

让我们看一个带有和不带有Subject的示例。 我们将看到Subject如何使我们免于冗余操作。

Observable<Integer> observable =
                Observable.just(1, 2).subscribeOn(Schedulers.computation())
                        .map(val -> {
                            System.out.println("map operation. Squaring : " + val * val);
                            return val;
                        });

        observable.subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("first subscriber : " + integer);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

        observable.subscribe(l ->
                System.out.println("second subscriber :" + l));

We’ve subscribed two Observers. Let’s see what the output prints.

我们已订阅了两名观察员。 让我们看看输出显示了什么。

The map operation is computed each time for each observer.

每次为每个观察者计算地图操作。

By using Subject we can remove this redundancy as shown below:

通过使用Subject,我们可以删除此冗余,如下所示:

Observable<Integer> observable =
                Observable.just(1, 2).subscribeOn(Schedulers.computation())
                        .map(val -> {
                            System.out.println("map operation. Squaring : " + val * val);
                            return val;
                        });


        PublishSubject<Integer> pSubject = PublishSubject.create();
        observable.subscribe(pSubject);


        pSubject.subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("First Subscriber");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        });


        pSubject.subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("Second Subscriber");
            }

            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }

            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        });

PublishSubject is a subclass of Subject.

PublishSubjectSubject的子类。

The output is:

输出为:

So the map operation isn’t repeated for the second subscriber.
Thus the Subject multicasts to all of its subscribers. That means that the data would be emitted and computed just once.

因此,第二个订户不会重复执行映射操作。
因此,主题将多播到其所有订户。 这意味着数据将仅被发射和计算一次。

Cold Observables vs Hot Observables 冷可观察物vs热可观察物

Let’s explain this with a metaphor.

让我们用一个隐喻来解释一下。

Case 1
You are watching a movie on Youtube. You call your friend and tell him to subscribe to that channel and watch it too. He opens his Youtube and starts the movie.

情况1
您正在YouTube上看电影。 您呼叫朋友并告诉他订阅该频道并观看。 他打开自己的Youtube并开始播放电影。

Case 2
You are watching a live cricket/football match. Your friend joins you after some time.

情况二
您正在看现场板球/足球比赛。 一段时间后,您的朋友加入了您。

In Case 1, you and your friend would be able to watch the full movie from the beginning.
In Case 2, the friend won’t be able to watch the match from the beginning.

在案例1中,您和您的朋友将从一开始就可以观看整部电影。
在案例2中,朋友从一开始就无法观看比赛。

  • Case 1 = Cold Observables. All observers would get the emissions from the beginning.

    情况1 =冷观测值。 所有观察员将从一开始就获得排放。
  • Case 2 = Hot Observables. Every Observer would receive emissions only from the point when they subscribed.

    情况2 =热观测值。 每个观察员仅在订阅时才接收排放。

主题是可观察的热点 (Subjects are Hot Observables)

Now that we’re clear about Hot Observables, let’s validate whether Subjects are Hot Observables or not with an example:

现在我们已经了解了热可观测对象,下面通过一个示例来验证主题是否为热可观测对象:

PublishSubject<Integer> pSubject = PublishSubject.create();


        pSubject.onNext(0);

        pSubject.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        pSubject.onNext(1);
        pSubject.onNext(2);


        pSubject.subscribe(it -> {
            System.out.println("Observer 2 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 2 onCompleted"), on1 -> System.out.println("Observer 2 onSubscribe"));

        pSubject.onNext(3);

        pSubject.subscribe(it -> {
            System.out.println("Observer 3 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 3 onCompleted"), on1 -> System.out.println("Observer 3 onSubscribe"));

        pSubject.onNext(4);
        pSubject.onComplete();

The output printed in the console is:

控制台中输出的输出为:

As you can see the Observer 2 and Observer 3 don’t get the values emitted by the Subject before the point of subscription.

如您所见,观察者2和观察者3在订阅点之前未获得主题发出的值。

Another metaphor for Hot Observables – They are like Whatsapp Group messages. You can only read messages after joining the group
Hot Observable的另一个隐喻–它们就像Whatsapp Group消息一样。 加入论坛后,您只能阅读邮件

学科类型 (Types of Subject)

Following are the different types of Subjects. Each works differently.

以下是不同类型的主题。 每个工作原理都不同。

  • PublishSubject

    发布主题
  • BehaviorSubject

    行为主体
  • AsyncSubject

    异步主题
  • ReplaySubject

    重播主题
  • UnicastSubject

    单播主题
  • SingleSubject

    单科

发布主题 (PublishSubject)

This emits all the items at the point of subscription. This is the most basic form of Subject and we’ve implemented it above.

这将在订阅时发出所有项目。 这是Subject的最基本形式,我们已经在上面实现了。

行为主体 (BehaviorSubject)

An observer, when subscribed to the BehaviorSubject, would get the last emitted item before it subscribed and all subsequent items.

观察者在订阅BehaviorSubject时,将获得订阅之前的最后一个发射项目以及所有后续项目。

Metaphor: Your friend gets to watch the last replay when he joins for the cricket match besides viewing the rest of the live match.
隐喻:您的朋友参加板球比赛时除了观看现场比赛的其余部分外,还可以观看最后一次重播。

Example:

例:

BehaviorSubject<Integer> behaviorSubject = BehaviorSubject.create();


        behaviorSubject.onNext(0);

        behaviorSubject.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        behaviorSubject.onNext(1);
        behaviorSubject.onNext(2);


        behaviorSubject.subscribe(it -> {
            System.out.println("Observer 2 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 2 onCompleted"), on1 -> System.out.println("Observer 2 onSubscribe"));

        behaviorSubject.onNext(3);

        behaviorSubject.subscribe(it -> {
            System.out.println("Observer 3 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 3 onCompleted"), on1 -> System.out.println("Observer 3 onSubscribe"));

        behaviorSubject.onNext(4);
        behaviorSubject.onComplete();

Output:

输出:

异步主题 (AsyncSubject)

Of all the emissions, AsyncSubject would emit only the last item. That too only when onComplete() gets called.

在所有发射中,AsyncSubject仅发射最后一个项目。 仅在调用onComplete()时也是如此。

Metaphor: You turned on your television to watch the live cricket match and its the last ball of the game. If your friend joins you late, he/she can also just see the last ball of the game.
隐喻:您打开电视观看现场板球比赛及其比赛的最后一个球。 如果您的朋友加入您的时间较晚,他/她还可以看到游戏的最后一个球。

Example:

例:

AsyncSubject<Integer> asyncSubject = AsyncSubject.create();


        asyncSubject.onNext(0);
        
        asyncSubject.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        asyncSubject.onNext(1);
        asyncSubject.onNext(2);
        asyncSubject.onComplete();


        asyncSubject.subscribe(it -> {
            System.out.println("Observer 2 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 2 onCompleted"), on1 -> System.out.println("Observer 2 onSubscribe"));

        asyncSubject.onNext(3);

Output:

输出:

As you can see if the onComplete was called before the second observer subscribed, still that observer would get the last emitted value, even if it was before it subscribed.

如您所见,如果onComplete在第二个观察者订阅之前被调用,则即使该观察者在订阅之前,该观察者仍将获得最后发出的值。

重播主题 (ReplaySubject)

As the name says, when an observer subscribes to a ReplaySubject, it would get all the items from the beginning.

顾名思义,当观察者订阅ReplaySubject时,它将从头开始获取所有项目。

Metaphor: Your friend who had missed the live cricket match can now replay the whole. He probably recorded it!
隐喻:您错过现场板球比赛的朋友现在可以重播整个比赛。 他可能记录下来了!

Example:

例:

ReplaySubject<Integer> replaySubject = ReplaySubject.create();


        replaySubject.onNext(0);


        replaySubject.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        replaySubject.onNext(1);
        replaySubject.onNext(2);


        replaySubject.subscribe(it -> {
            System.out.println("Observer 2 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 2 onCompleted"), on1 -> System.out.println("Observer 2 onSubscribe"));

        replaySubject.onNext(3);

        replaySubject.subscribe(it -> {
            System.out.println("Observer 3 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 3 onCompleted"), on1 -> System.out.println("Observer 3 onSubscribe"));

        replaySubject.onNext(4);
        replaySubject.onComplete();

Output:

输出:

单播主题 (UnicastSubject)

A UnicastSubject can have a single observer only. Otherwise it will throw an error. Also it emits all the values from the beginning.

UnicastSubject只能有一个观察者。 否则会抛出错误。 它还从一开始就发出所有值。

Metaphor: You and only you are watching the live cricket match. You can rewind it. If your friend comes your television screen won’t be visible to him. It will still be to you.
隐喻:您和您只有在观看现场板球比赛。 您可以倒带。 如果您的朋友来,您的电视屏幕将对他不可见。 仍然会属于你。

Example:

例:

UnicastSubject<Integer> unicastSubject = UnicastSubject.create();


        unicastSubject.onNext(0);


        unicastSubject.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> System.out.println("Observer 1 onError"), () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        unicastSubject.onNext(1);
        unicastSubject.onNext(2);


        unicastSubject.subscribe(it -> {
            System.out.println("Observer 2 onNext: " + it);
        }, (Throwable onError) ->
                System.out.println("Observer 2 onError"), () -> System.out.println("Observer 2 onCompleted"), on1 -> System.out.println("Observer 2 onSubscribe"));

        unicastSubject.onNext(3);

Output:

输出:

单科 (SingleSubject)

Last but not the least, a SingleSubject can emit only one item to all its observers. Multiple observers can subscribe to it. It can subscribe to multiple SingleObservables.

最后但并非最不重要的一点是,SingleSubject只能向其所有观察者发射一项。 多个观察者可以订阅它。 它可以订阅多个SingleObservables。

Metaphor: You can only watch the last ball of the match. Your friend can also just watch the single last ball of the match.
隐喻:您只能观看比赛的最后一个球。 您的朋友也可以只观看比赛的最后一个球。

Example:

例:

Single<Integer> singleObservable = Single.just(1)
                .subscribeOn(Schedulers.computation());
        Single<Integer> singleObservableTwo = Single.just(2)
                .subscribeOn(Schedulers.computation());

        SingleSubject<Integer> singleSubject = SingleSubject.create();
        singleObservable.subscribe(singleSubject);
        singleObservableTwo.subscribe(singleSubject);


        singleSubject.subscribe(integer -> System.out.println("Observer 1 onNext: " + integer), error -> System.out.println("onError"));
        singleSubject.subscribe(integer -> System.out.println("Observer 2 onNext: " + integer), error -> System.out.println("onError"));

Output:

输出:

PS: We can set transformation operators on the Subject in the same way as we do on Observables:

PS:我们可以像在Observables上一样,在Subject上设置转换运算符:

PublishSubject<Integer> publishSubject = PublishSubject.create();

        Observable<Integer> observable = publishSubject.filter(it-> it%2==0);

        publishSubject.onNext(0);


        observable.subscribe(it -> {
            System.out.println("Observer 1 onNext: " + it);
        }, (Throwable onError) -> {
        }, () -> System.out.println("Observer 1 onCompleted"), on1 -> System.out.println("Observer 1 onSubscribe"));

        publishSubject.onNext(1);
        publishSubject.onNext(2);

Only 2 would be printed.

仅打印2张。

And that sums up RxJava Subject for us.

这就为我们总结了RxJava Subject。

翻译自: https://www.journaldev.com/22573/rxjava-subject

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值