web-dev-qa-db-fra.com

Opérateur Concat VS Merge

Je vérifiais la documentation de RXJava et je remarque que les opérateurs de concaturation et de fusion semblent faire de même ... J'ai écrit quelques tests pour en être sûr.

@Test
public void testContact() {

    Observable.concat(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
              .subscribe(System.out::println);
}

@Test
public void testMerge() {

    Observable.merge(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
            .subscribe(System.out::println);
}

La documentation dit 

L'opérateur de fusion est également similaire. Il combine les émissions de deux ou plusieurs observables, mais peut les imbriquer, alors que Concat n'entrelace jamais les émissions de plusieurs observables.

Mais je ne comprends toujours pas tout à fait, en exécutant ce test des milliers de fois, le résultat de la fusion est toujours le même. Comme l'ordre n'est pas accordé, je m'attendais parfois à un "monde" "bonjour" "réactif" par exemple.

Le code est ici https://github.com/politrons/reactive

31
paul

C’est ce qui est décrit dans la documentation que vous avez citée - merge peut entrelacer les sorties, tandis que concat attend d’abord la fin des flux précédents avant de traiter les flux ultérieurs . toute différence réelle (mais en théorie, la fusion pourrait produire des mots dans un ordre aléatoire et rester valide selon les spécifications). Si vous voulez voir la différence, essayez de suivre (vous devrez ajouter un peu de sommeil après pour éviter une sortie prématurée)

    Observable.merge(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 B0 A1 B1 B2 A2 B3 A3 B4 A4

versus

    Observable.concat(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 A1 A2 A3 A4 A5 A6 A7 A8

Concat ne commencera jamais à imprimer B, car le flux A ne se termine jamais.

s/stream/observable/g;)

La documentation donne des graphiques de Nice pour montrer la différence. N'oubliez pas que la fusion ne donne pas garantie d'entrelacement d'éléments un par un, il s'agit simplement d'un exemple possible.

Concat

 Concat operator Fusion

 Merge operator

109
Artur Biesiadowski

Concat

Concat émet les émissions de deux ou plusieurs observables sans les entrelacer. Il maintiendra l'ordre des observables tout en émettant les éléments. Cela signifie qu'il émettra tous les éléments du premier observable, puis tous les éléments du deuxième observable, etc.

 Concat Operator

Comprenons cela clairement par un exemple.

final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};

final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);

Observable.concat(observableFirst, observableSecond)
        .subscribe(new Observer<String>() {

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String value) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

Comme nous utilisons Concat Operator, il va maintenir l’ordre et émettre les valeurs A1, A2, A3, A4, B1, B2, B3.

Fusionner

La fusion combine plusieurs observables en un seul en fusionnant leurs émissions. Il ne maintiendra pas l'ordre tout en émettant les éléments.

 Merge Operator

Comprenons cela clairement par un exemple.

final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};

final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);

Observable.merge(observableFirst, observableSecond)
        .subscribe(new Observer<String>() {

            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(String value) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

Comme nous utilisons Merge Operator, il ne conserve pas l'ordre et peut émettre les valeurs dans n'importe quel ordre, par exemple A1, B1, A2, A3, B2, B3, A4 ou A1, A2, B1, B2 , A3, A4, B3 ou peuvent être n'importe quoi.

C'est ainsi que nous devrions utiliser les opérateurs Concat et Merge dans RxJava en fonction de notre cas d'utilisation.

0
Amit Shekhar