Ich kann es lesen! RxJava

Überblick

Wenn ich die in RxJava geschriebene Quelle zum ersten Mal sehe, ist der Prozessablauf schwer zu verfolgen. Es gibt viele Fälle, in denen wir den Teil der Logik, den wir ursprünglich verstehen wollen, nicht verstehen können. (Zumindest war ich ...)

Dieser Artikel ist die Hauptklassen und Methoden von RxJava,

Indem Sie dem Vorgang folgen, während Sie den Code tatsächlich verschieben, Lesen Sie die Leser! RxJava ”.

Ziel

――Was ist RxJava köstlich?

observable.png

** "Ich verstehe die Bedeutung dieser Figur nicht! !! 』** Ich werde es dir schicken.

Ausführungsumgebung

Im Fall von Gradle schreiben Sie einfach Folgendes.

build.gradle


repositories {
    mavenCentral()
    maven { url 'https://oss.jfrog.org/libs-snapshot' }
}

dependencies {
    compile 'io.reactivex.rxjava2:rxjava:2.2.0-SNAPSHOT'
}

Für andere Personen beachten Sie bitte Folgendes. https://github.com/ReactiveX/RxJava

Darüber hinaus wird Lambda als Grundvoraussetzung verwendet. Wenn Sie sich Sorgen um Lambda machen, lernen Sie bitte Folgendes. https://qiita.com/sanotyan1202/items/64593e8e981e8d6439d3

Beispielcode

Beispielcode ist unten. Es funktioniert so wie es ist, also versuchen Sie es bitte.

https://github.com/youyanntoto/RxJavaSample

Darüber hinaus wird in diesem Band hauptsächlich der Beispielcode erläutert.

Hauptgeschichte

Informationen zum Verarbeitungsinhalt des Beispielcodes

Main.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
        RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
        RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);

        System.out.println(tokyoWeather);
        System.out.println(yokohamaWeather);
        System.out.println(nagoyaWeather);

        System.out.println("*** main end ***");
    }

RestUtil.java


    public static Weather getWeather(Place place) {
        Weather weather;

        //Holen Sie sich das Wetter passend für jeden Ort
        switch (place) {
            case TOKYO:
                weather = Weather.SUNNY;
                break;
            case YOKOHAMA:
                weather = Weather.RAINY;
                break;
            case NAGOYA:
                weather = Weather.WINDY;
                break;
            default:
                weather = Weather.SUNNY;
                break;
        }

        try {
            //Kommunikationsverarbeitungszeit 500~Lass es 999ms dauern
            Thread.sleep(new Random().nextInt(500) + 500);
        } catch (InterruptedException e) {
            // nop
        }

        return weather;
    }

Siehe die Hauptklasse. Rest-Kommunikation durchführen (RestUtil # getWeather (RestUtil.Place)) Führt den Vorgang aus, um das Wetter (RestUtil.Weather) im angegebenen Bereich zu erfassen.

Wie Sie in der RestUtil-Klasse sehen können, ist der Kommunikationsprozess selbst ein Dummy.

RestUtil.getWeather benötigt jetzt jeweils 500-999 ms. Wenn Sie also Main.java ausführen, dauert es ungefähr 1500-3000 ms von 500-999 ms x 3.

Lassen Sie uns nun den obigen Code reaktivieren.

Teil 1. "Fertigstellbar", um die Fertigstellung mitzuteilen

Beispielcode

CompletableSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Completable.create(emitter -> {
            RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
            RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
            RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);

            System.out.println(tokyoWeather);
            System.out.println(yokohamaWeather);
            System.out.println(nagoyaWeather);
            emitter.onComplete();

        }).subscribe(() -> {
            System.out.println("Complete!!");

        }, throwable -> {
            System.out.println("Error!!");
            throwable.printStackTrace();

        });

        System.out.println("*** main end ***");
    }

Kommentar

Zunächst wird die Verarbeitung des Arguments Completable.create (im Lambda) ausgeführt. Die Verarbeitung selbst entspricht der Verarbeitung von Main.java zu Beginn.

Als nächstes emitter.onComplete () Beim Aufruf wird das erste Argument von subscribe ausgeführt.

Das zweite Argument von subscribe ist übrigens, wenn Sie emitter.onError () aufrufen. Alternativ wird es ausgeführt, wenn ein Fehler im Lambda des Arguments Completable.create ausgelöst wird. Das dort übergebene Wurfobjekt ist das Fehlerobjekt, das im Fehlerfall aufgetreten ist.

Zusammenfassung, Verarbeitung von Completable.create-Argumenten → Abonnieren Sie die Verarbeitung des ersten Arguments (onSuccess) oder des zweiten Arguments (onError) Der Prozess wird im Ablauf ausgeführt.

Teil 2. "Single" übergibt einen Wert

Beispielcode

SingleSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Single.<List<RestUtil.Weather>>create(emitter -> {
            RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
            RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
            RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
            emitter.onSuccess(List.of(tokyoWeather, yokohamaWeather, nagoyaWeather));

        }).subscribe(weathers -> {
            System.out.println("Complete!!");
            for (RestUtil.Weather weather : weathers) {
                System.out.println(weather);
            }
            
        }, throwable -> {
            System.out.println("Error!!");
            throwable.printStackTrace();
            
        });

        System.out.println("*** main end ***");
    }

Kommentar

Wie der Abschluss von Teil 1 Behandlung von Single.create-Argumenten → Abonnieren Sie die Verarbeitung des ersten Arguments (onSuccess) oder des zweiten Arguments (onError) Der Prozess wird im Ablauf ausgeführt.

Der Unterschied ist der Ort, an dem das Wetter ausgegeben wird.

In Single können Sie also nur einen Wert an die nachfolgende Verarbeitung übergeben Listen Sie das Wetter in jedem Gebiet auf emitter.onSuccess(T) Durch Aufrufen wird es an die Verarbeitung des ersten Arguments von subscribe übergeben. Darüber hinaus wird der Typ des dort übergebenen Arguments von den Generika zum Zeitpunkt der Erstellung von Single # angegeben.

Wenn Sie sich in JavaScript mit Promise befasst haben, ist das Bild ähnlich.

Teil 3. (Extra Edition) "Stream"

Beispielcode

StreamSample.java


/**
 * sample for Stream
 */
    public static void main(String[] args) {
        System.out.println("*** main start ***");

        RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
        RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
        RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);

        Stream.of(List.of(tokyoWeather, yokohamaWeather, nagoyaWeather))
                .forEach(weather -> {
                    System.out.println(weather + "");
                });

        System.out.println("*** main end ***");
    }

Kommentar

Bevor wir über Observable sprechen, wollen wir etwas über Stream lernen. Wenn Sie Stream bereits verstehen, überspringen Sie es.

Dann ist der Ablauf der Verarbeitung, Ermitteln Sie zunächst das Wetter für jeden Bezirk und erstellen Sie eine Liste. Es wird gestreamt und das Wetter jedes Bezirks ausgegeben.

Die Form, in der die Werte nacheinander fließen, ähnelt Observable, das im Folgenden erläutert wird. Bitte verstehen Sie den Prozessablauf.

Teil 4. "Beobachtbar", der mehrere Werte übergibt

Beispielcode

ObservableSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Observable.<RestUtil.Weather>create(emitter -> {
            RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
            emitter.onNext(tokyoWeather);

            RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
            emitter.onNext(yokohamaWeather);

            RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
            emitter.onNext(nagoyaWeather);

            emitter.onComplete();

        }).subscribe(weather -> {
            System.out.println("Next!!");
            System.out.println(weather);

        }, throwable -> {
            System.out.println("Error!!");
            throwable.printStackTrace();

        }, () -> {
            System.out.println("Complete!!");

        });

        System.out.println("*** main end ***");
    }

Kommentar

Im Gegensatz zu herkömmlichen Completable und Single, Es gibt drei Argumente für das Abonnieren.

Als Verarbeitungsablauf Der Observable.create-Prozess wird zuerst ausgeführt. Danach wird das erste Argument von subscribe jedes Mal ausgeführt, wenn emitter.onNext (T) aufgerufen wird. Wenn schließlich emitter.onComplete () aufgerufen wird, wird das dritte Argument von subscribe ausgeführt. Das zweite Argument ist der Prozess, der wie in der Vergangenheit aufgerufen wird, wenn ein Fehler auftritt.

Zusammenfassung, Observable.create-Verarbeitung → Abonnieren Sie die Verarbeitung des ersten Arguments (onNext) oder des zweiten Arguments (onError) → Verarbeitung des dritten Arguments (onComplete) von subscribe Der Prozess wird im Ablauf ausgeführt.

Observable kann mehrere Werte übergeben, sodass der Wert bei jeder Kommunikation ausgegeben werden kann.

Teil 5. "subscribeOn", "ObservOn", um den Thread anzugeben

Beispielcode

ThreadSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Observable.<RestUtil.Weather>create(emitter -> {
            RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
            emitter.onNext(tokyoWeather);

            RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
            emitter.onNext(yokohamaWeather);

            RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
            emitter.onNext(nagoyaWeather);

            emitter.onComplete();

        }).subscribeOn(Schedulers.io())
                .observeOn(Schedulers.newThread())
                .subscribe(weather -> {
                    System.out.println("Next!!");
                    System.out.println(weather);

                }, throwable -> {
                    System.out.println("Error!!");
                    throwable.printStackTrace();

                }, () -> {
                    System.out.println("Complete!!");

                });

        System.out.println("*** main end ***");
    }

Kommentar

In dem in Teil 4 erläuterten Quellcode "subscribeOn", "observeOn" Wurde hinzugefügt.

Es gibt einige Vorteile von RxJava, Das größte davon ist, dass der Prozess der Angabe dieses Threads einfach zu schreiben ist.

"subscribeOn" gibt den Verarbeitungsthread in Observable.create an. "watchOn" kann den Verarbeitungsthread in subscribe angeben.

Im obigen Beispiel wird die Kommunikationsverarbeitung von einem E / A-Thread ausgeführt. Die nachfolgende Verarbeitung (Verarbeitung, die das Kommunikationsergebnis verwendet) wird von einem anderen Thread ausgeführt.

Als häufig verwendete Szene wird in der Android-Entwicklung die Kommunikationsverarbeitung in einem separaten Thread ausgeführt. Es ist eine Standardpraxis, dass der Hauptthread die Verarbeitung ausführt, die die Ansicht in der nachfolgenden Verarbeitung behandelt.

Teil 6. Konvertieren Sie den Wert "map"

Beispielcode

ObservableMapSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Observable.<RestUtil.Weather>create(emitter -> {
            RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
            emitter.onNext(tokyoWeather);

            RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
            emitter.onNext(yokohamaWeather);

            RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
            emitter.onNext(nagoyaWeather);

            emitter.onComplete();

        }).map(weather -> {
            switch (weather) {
                case SUNNY:
                    return "happy day!!";
                case RAINY:
                    return "sad day...";
                case WINDY:
                default:
                    return "normal day";
            }

        }).subscribe(weather -> {
            System.out.println("Next!!");
            System.out.println(weather);

        }, throwable -> {
            System.out.println("Error!!");
            throwable.printStackTrace();

        }, () -> {
            System.out.println("Complete!!");

        });

        System.out.println("*** main end ***");
    }

Kommentar

Dem Quellcode von Teil 4 wurde eine neue Methodenzuordnung hinzugefügt. Sie können sehen, dass Sie es tatsächlich bewegen können, Der an das erste Argument von subscribe übergebene Wert wurde ** konvertiert **.

Wie Sie sehen können, wird der an die Karte übergebene Prozess konvertiert.

Die Karte empfängt den fließenden Wert und gibt den konvertierten Wert in der Rückgabeklausel zurück. Sie können den zu sendenden Wert in die nachfolgende Verarbeitung konvertieren.

Teil 7. Schließen Sie "flatMap" an

Beispielcode

ObservableFlatMapSample.java


    public static void main(String[] args) {
        System.out.println("*** main start ***");

        Observable.<RestUtil.Place>create(emitter -> {
            emitter.onNext(RestUtil.Place.TOKYO);
            emitter.onNext(RestUtil.Place.YOKOHAMA);
            emitter.onNext(RestUtil.Place.NAGOYA);
            emitter.onComplete();

        }).flatMap(place -> {
            return Observable.create(emitter -> {
                RestUtil.Weather tokyoWeather = RestUtil.getWeather(place);
                emitter.onNext(tokyoWeather);
                emitter.onComplete();
            });

        }).subscribe(weather -> {
            System.out.println("Next!!");
            System.out.println(weather);

        }, throwable -> {
            System.out.println("Error!!");
            throwable.printStackTrace();

        }, () -> {
            System.out.println("Complete!!");

        });

        System.out.println("*** main end ***");
    }

Kommentar

Dem Quellcode von Teil 4 wurde eine neue Methode flatMap hinzugefügt. Der in der ersten Observable.create übergebene Wert hat sich von Wetter zu Region geändert. Ein weiteres Observable wird in flatMap generiert.

Der Verarbeitungsablauf ist Der erste Observable-Prozess wird ausgeführt. Jedes Mal, wenn emitter.onNext (T) aufgerufen wird Die Verarbeitung in der zweiten Observable, die in der flatMap zurückgegeben wird, wird ausgeführt. Mit anderen Worten, flatMap verbindet das erste Observable und das zweite Observable.

In diesem Beispiel ist der Kommunikationspunkt nur der zweite Observable, es gibt also keinen bestimmten Geschmack, aber Tatsächlich wird die DB-Verarbeitung mit dem ersten Observable durchgeführt. Die Kommunikationsverarbeitung wird mit dem zweiten Observable durchgeführt Es wird in Szenen verwendet, in denen eine separate zeitaufwändige Verarbeitung durchgeführt wird.

Am Ende

Mit dem oben genannten "Lesen! RxJava “ist vorbei.

Weil die Welt von RxJava weit ist und immer noch wächst Der Inhalt dieses Artikels reicht nicht aus, um alles abzudecken, Sie sollten in der Lage sein, die Grundlagen zu verstehen, indem Sie die hier vorgestellten Klassen und Methoden kombinieren und anwenden. (Zumindest im Sinne von Lesbarkeit)

Ich hoffe, ich kann jedem helfen, der in die Welt von RxJava eintauchen wird.

Recommended Posts

Ich kann es lesen! RxJava
Ich möchte NetBeans auf einem Mac verwenden → Ich kann es verwenden!
Ich werde es leicht posten
Ich habe module-info.java in java.base gelesen
Ich habe das Kotlin-Startbuch gelesen
Ich habe versucht, node-jt400 (IFS lesen)
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von Long gelesen
Kannst du es machen? Java EE
Ich habe die Quelle von Short gelesen
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
Heroku kann bereitgestellt werden, aber ich erhalte eine Fehlermeldung und kann sie nicht öffnen
Ich kann kein SQS verwenden, das den Fragebogen mit einem Scanner lesen kann. → Ich kann es nach dem Ändern der Java-Version verwenden