Ich denke darüber nach, dass Sie verwenden, flatMap
wenn die Funktion, die Sie in setzen map()
möchten, eine zurückgibt Observable
. In diesem Fall könnten Sie immer noch versuchen, es zu verwenden, map()
aber es wäre unpraktisch. Lassen Sie mich versuchen zu erklären, warum.
Wenn Sie sich in einem solchen Fall dazu entschließen, bei zu bleiben map
, würden Sie eine bekommen Observable<Observable<Something>>
. Wenn wir in Ihrem Fall beispielsweise eine imaginäre RxGson-Bibliothek verwenden, die eine Methode Observable<String>
aus ihrer toJson()
Methode zurückgibt (anstatt einfach eine zurückzugeben String
), sieht dies folgendermaßen aus:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}); // you get Observable<Observable<String>> here
An diesem Punkt wäre es ziemlich schwierig, subscribe()
eine solche Beobachtung zu machen. Darin würden Sie eine erhalten, Observable<String>
zu der Sie erneut subscribe()
den Wert benötigen würden . Welches ist nicht praktisch oder schön anzusehen.
Um es nützlich zu machen, besteht eine Idee darin, dieses Observable von Observables zu "glätten" (Sie könnten anfangen zu sehen, woher der Name _flat_Map kommt). RxJava bietet einige Möglichkeiten, um Observable zu reduzieren. Der Einfachheit halber nehmen wir an, dass das Zusammenführen das ist, was wir wollen. Beim Zusammenführen werden im Grunde genommen eine Reihe von Observablen verwendet und immer dann ausgegeben, wenn eine von ihnen ausgegeben wird. (Viele Leute würden argumentieren , dass ein Wechsel eine bessere Standardeinstellung wäre. Wenn Sie jedoch nur einen Wert ausgeben, spielt dies keine Rolle.)
Wenn wir also unser vorheriges Snippet ändern, erhalten wir:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}).merge(); // you get Observable<String> here
Dies ist viel nützlicher, da Sie beim Abonnieren (oder Zuordnen oder Filtern oder ...) nur den String
Wert erhalten. ( merge()
Wohlgemerkt , eine solche Variante von gibt es in RxJava nicht, aber wenn Sie die Idee der Zusammenführung verstehen, dann hoffe ich, dass Sie auch verstehen, wie das funktionieren würde.)
Also im Grunde genommen, weil solche merge()
wahrscheinlich immer nur dann nützlich sein sollten, wenn es gelingt map()
, ein Observable zurückzugeben, und Sie dies nicht immer wieder flatMap()
eingeben müssen , wurde es als Abkürzung erstellt. Die Zuordnungsfunktion wird wie gewohnt map()
angewendet, aber später werden die zurückgegebenen Werte nicht mehr ausgegeben, sondern "abgeflacht" (oder zusammengeführt).
Das ist der allgemeine Anwendungsfall. Dies ist am nützlichsten in einer Codebasis, die überall Rx verwendet, und Sie haben viele Methoden, die Observables zurückgeben, die Sie mit anderen Methoden verketten möchten, die Observables zurückgeben.
In Ihrem Anwendungsfall ist dies ebenfalls nützlich, da map()
nur ein emittierter Wert onNext()
in einen anderen emittierten Wert umgewandelt werden kann onNext()
. Es kann jedoch nicht in mehrere Werte umgewandelt werden, überhaupt keinen Wert oder einen Fehler. Und wie akarnokd in seiner Antwort schrieb (und wohlgemerkt , er ist viel schlauer als ich, wahrscheinlich im Allgemeinen, aber zumindest wenn es um RxJava geht), sollten Sie keine Ausnahmen von Ihrer machen map()
. Also stattdessen können Sie flatMap()
und verwenden
return Observable.just(value);
wenn alles gut geht, aber
return Observable.error(exception);
wenn etwas ausfällt.
In seiner Antwort finden Sie einen vollständigen Ausschnitt: https://stackoverflow.com/a/30330772/1402641
subscriber.onError()
usw. Alle Beispiele, die ich gesehen habe, haben Fehler auf diese Weise weitergeleitet. Ist das nicht wichtig?