简体   繁体   English

可观察的不是异步的

[英]Observable is not asynchronous

I am learning RxJava and am testing a scenario where I read data from a DB and then post it to a Queue. 我正在学习RxJava并正在测试从数据库读取数据,然后将其发布到队列的方案。 I just made a sample mock of the whole process but I don't seem to find the Observable working as I wanted it to ie. 我只是对整个过程进行了模拟,但我似乎找不到我想要的Observable工作。 asynchronously. 异步地。

This is my code: 这是我的代码:

package rxJava;

import java.util.ArrayList;
import java.util.List;

import rx.Observable;
import rx.Observer;
import rx.functions.Action1;

public class TestClass {

    public static void main(String[] args) {

        TestClass test = new TestClass();
        System.out.println("---START---");

        test.getFromDB().subscribe(new Observer<String>() {

            @Override
            public void onCompleted() {
                System.out.println("Publish complete.");
            }

            @Override
            public void onError(Throwable t) {
                System.out.println(t.getMessage());
            }

            @Override
            public void onNext(String s) {
                test.publishToQueue(s).subscribe(new Observer<Boolean>() {

                    @Override
                    public void onNext(Boolean b) {
                        if (b) {
                            System.out.println("Successfully published.");
                        }
                    }

                    @Override
                    public void onCompleted() {
                    }

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

    public Observable<String> getFromDB() {

        List<String> list = new ArrayList<String>();
        for (int i = 0; i < 30; i++) {
            list.add(Integer.toString(i));
        }
        return Observable.from(list).doOnNext(new Action1<String>() {
            @Override
            public void call(String temp) {
                if (temp.contains("2")) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

    }

    public Observable<Boolean> publishToQueue(String s) {

        return Observable.defer(() -> {
            try {
                if (s.contains("7")) {
                    Thread.sleep(700);
                }
                System.out.println("Published:: " + s);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Observable.just(true);
        });
    }
}

Suppose I get a list from the DB asynchronously and want to post it to the queue,. 假设我异步地从数据库获取列表,并希望将其发布到队列中。 I have used an Observable returned from getFromDB and have subscribed to it which mimics the data I get from DB. 我使用了一个从getFromDB返回的Observable ,并订阅了它,它模仿了我从DB获取的数据。 Every time I get the data from DB , I want to push it to a queue using publishToQueue which also returns an Observable . 每次从数据库获取数据时,我都想使用publishToQueue将其推送到队列,该队列还返回一个Observable I wanted to make the queue call also asynchronous. 我想使队列调用也异步。 Now on positive acknowledgement from the queue such as the Boolean which I am returning ( Observable<Boolean> ), I want to print something. 现在,从队列肯定的确认,如Boolean ,我是回( Observable<Boolean> ),我想打印的东西。

So basically I just want both the processes to be asynchronous. 所以基本上我只希望两个过程都是异步的。 For every data from DB, I push it to the Queue asynchronously. 对于数据库中的每个数据,我都将其异步推送到队列。

I have added Thread.sleep() in both the methods, db call and queue so as to mimic a delay and to test the asynchronous operations. 我在两种方法(数据库调用和队列Thread.sleep()中都添加了Thread.sleep() ,以便模拟延迟并测试异步操作。 I think this is what causing the problem. 我认为这是导致问题的原因。 But I also tried Obseravable.delay() but that doesn't even produce any output. 但是我也尝试了Obseravable.delay()但是它甚至不会产生任何输出。

Please help me understand how this works and how I can make it work as I want it to. 请帮助我了解它的工作原理以及如何使其按我的意愿工作。

You have to specified subscribeOn value. 您必须指定subscribeOn值。

Observable.just("one", "two", "three", "four", "five")
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(/* an Observer */);

http://reactivex.io/documentation/operators/subscribeon.html http://reactivex.io/documentation/operators/subscribeon.html

By default, RxJava is synchronous . 默认情况下,RxJava是同步的 It means that everything will be perform in the same thread (and the current thread), by default. 这意味着默认情况下,所有操作都将在同一线程(和当前线程)中执行。 You can perform tasks in another thread thanks to observeOn / subscribeOn methods, or using some operators that perform tasks in another job (because it use another scheduler, like delay , interval , ...) 您可以observeOn / subscribeOn方法在另一个线程中执行任务,或者使用一些在另一个作业中执行任务的运算符(因为它使用另一个调度程序,例如delayinterval ,...)

In your example, you have to explitly set in which scheduler the subscription will pe performed. 在您的示例中,您必须明确设置将在哪个调度程序中执行订阅。 (here, in which thread Observable.from will emit your list) (在这里, Observable.from线程将在其中发出您的列表)

test.getFromDb()
    .subscribeOn(Schedulers.io())
    .subscribe();

Then you can use the flatMap operator and calling your publishToQueue method. 然后,您可以使用flatMap运算符并调用publishToQueue方法。 This method will be executed in the previous scheduler, but you can force it to use another scheduler, thanks to observeOn method. 该方法将在先前的调度程序中执行,但是由于使用了observeOn方法,您可以强制其使用另一个调度程序。 Everything after the observeOn method will be executed in another thread. observeOn方法之后的所有内容都将在另一个线程中执行。

 test.fromDb()
     .subscribeOn(Schedulers.io())
     .observeOn(Schedulers.computation())
     .flatMap(l -> test.publishToqueue(l))
     .subscribe();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM