I tuoi esempi non sono equivalenti semanticamente:
Observable<T> observable = getData()
observable.subscribe(onSuccess, onError, onCompletion)
eseguirà le procedure onSuccess, onError ogni volta che viene ricevuto un nuovo elemento.
D'altra parte, con
Iterable<Future<T>> futures = getData()
futures.forEach(future => future.onSuccess(onSuccess), future.onError(onError))
l'iterable consegna tutti i futures e tu registrati i callback su ogni futuro mentre lo ottieni dal iterable. Ma, a questo punto, il futuro potrebbe ancora essere in esecuzione. Successivamente, questi futures possono essere completati in qualsiasi ordine, non necessariamente nell'ordine in cui sono stati forniti dall'iter iterabile.
Inoltre, la prima soluzione può ricevere un flusso di dati possibilmente illimitato senza bloccare: ogni volta che arriva un nuovo elemento, viene richiamata una richiamata.
La seconda soluzione non può: ha senso solo se vuoi iniziare un finito
numero di calcoli asincroni.
Per avere una migliore intuizione, dai un'occhiata alla tabella su questa pagina o
questo (grazie a @Laiv per il link, non sono stato in grado di ritrovarlo).
-
Nella tua prima soluzione hai più valori spinti in modo asincrono nel tuo programma (in basso a destra della tabella).
-
Nella tua seconda soluzione hai più valori tirati in modo sincrono dal tuo programma. A turno, ognuno di questi valori è un calcolo che spinge asincronamente un singolo valore.
Un esempio di ciò che puoi fare con la prima soluzione è il seguente. Supponiamo di avere un osservabile che rappresenta tutti gli eventi della GUI in un'applicazione:
Observable<Event> events = ...
Ora se vuoi ascoltare solo gli eventi di un determinato pulsante che è,
diciamo, identificato dalla sua etichetta "HelpButton", puoi scrivere l'osservabile:
Observable<Event> helpButtonEvents =
events.filter(e => "HelpButton".equals(e.getName()))
helpButtonEvents.subscribe(onHelpInvoked, ..., ...)
Dovrebbe essere chiaro che non puoi usare un iterable di futuro qui, perché non sai quanti eventi della GUI avrai e quindi avresti bisogno di avere un iteratore che esegue il polling sugli eventi per sempre.