RxJava watchOn()问题

时间:2019-08-19 08:54:51

标签: rx-java reactive-programming rx-java2

我分别订阅了两个PublishSubject和两个Observer。在PubslishSubjectSubscriber之间,我使用observeOn(Schedulers.single())从[main]线程切换到[RxSingleScheduler]线程。我开始在循环内的两个PubslishSubject.onNext()上发布(PublishSubject)。

publishSubject1.onNext("next");
publishSubject2.onNext("next");

我期望两个订阅者的运行顺序与发布排放的顺序相同,但是我得到的结果完全不同。 Subsriber1处理所有排放,然后Subscriber2处理所有排放。 我预计排放将按计划并按发布顺序运行。有没有办法做到这一点?

import java.util.concurrent.TimeUnit;

import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;

public class ObserveOnApp {

    public static void main(String[] args) {
        PublishSubject<String> publishSubject1 = PublishSubject.create();
        PublishSubject<String> publishSubject2 = PublishSubject.create();

        publishSubject1
        .observeOn(Schedulers.single())
        .subscribe(next -> {
            System.out.println("Subscriber1");
        });

        publishSubject2
        .observeOn(Schedulers.single())
        .subscribe(next -> {
            System.out.println("Subscriber2");
        });

        for (int i= 0; i < 10; i++) {
            publishSubject1.onNext("next");
            publishSubject2.onNext("next");
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2 个答案:

答案 0 :(得分:0)

Schedulers Single用于按顺序执行工作,请检查其documentation

  

返回一个默认的,共享的,单线程支持的Scheduler实例,用于需要在同一后台线程上强顺序执行的工作。

顺便说一句,在运行了几次代码之后,我很幸运地使Subscribe1发出了一次,然后Subscribe2完成了工作,Subscribe1完成了:

Subscriber1 // <- 1 started first!
Subscriber2 // <- then 2 started
Subscriber2
Subscriber2
...
Subscriber2
Subscriber2
Subscriber2 // <- 2 finished
Subscriber1 // <- 1 continued
Subscriber1
Subscriber1
...

如果您对使用single调度程序没有特殊要求,请尝试使用newThreadio,结果将更像:

Subscriber1
Subscriber1
Subscriber2
Subscriber1
Subscriber2
Subscriber1
Subscriber2
Subscriber2

如果您始终要发射相同的项目,则不需要创建多个PublishSubject,则可以使用publish进行多播,并在决定开始发射项目时调用connect。您还可以使用autoconnect并传递将触发项目发射的连接数:

        PublishSubject<String> publishSubject1 = PublishSubject.create();

        Observable<String> stringObservable = publishSubject1.publish().autoConnect(2);

        stringObservable
                .observeOn(Schedulers.io())
                .subscribe(next -> System.out.println("Subscriber1"));

        stringObservable
                .observeOn(Schedulers.io())
                .subscribe(next -> System.out.println("Subscriber2"));

        for (int i= 0; i < 10; i++) {
            publishSubject1.onNext("next");
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

答案 1 :(得分:0)

如果我了解您的期望,则应使用list而不是list(True) TypeError: 'bool' object is not iterable

subscribeOn有点棘手,因为它指出了可观察的“开始”在哪个线程上,而observeOn则允许您在运算符序列的“中间”切换线程

在这里查看subscribeOn和observeOn之间的区别: https://medium.com/upday-devs/rxjava-subscribeon-vs-observeon-9af518ded53a