fromCallable y defer tienen una implementación diferente. Escuché que algunos dicen que defer ayuda con la recursividad, pero no puedo producir ningún código que muestre la diferencia entre ellos.
Intenté con la implementación de números infinitos:
private Observable<Integer> numbers(int start) { return Observable.just(start) .concatWith(Observable.defer(() -> numbers(start + 1))); }pero sigo recibiendo una excepción de desbordamiento de pila al suscribirme
fromCallable crea un observable que emite un valor único y luego se completa.
defer pospone la creación del observable real hasta que se suscriba. Por lo tanto, puede crear observables de varios valores en función del estado en el momento de la suscripción. Por ejemplo:
Observable<Integer> daysOfWeekLeft = Observable.defer(() -> Observable.range(currentDayOfWeek(), 7 - currentDayOfWeek())); Básicamente puedes lograr lo mismo con fromCallable así:
Observable<Integer> daysOfWeekLeft = Observable.fromCallable(() -> currentDayOfWeek()) .flatMap(day -> Observable.range(day, 7 - day));PD. Su código para un flujo infinito de números da como resultado una recursividad infinita. Puede que tenga que jugar con programadores para evitar eso.
Lo estaba viendo en términos de Single , que es menos complicado que Observable, porque solo puede tener 1 valor. (es decir, un observable con 1 emisión). Lo siguiente también se aplica a los otros tipos (Observable, Flowable, Completable)
Single.fromCallable Single.fromCallable en realidad crea un nuevo Single a partir del valor dentro de la función a la que llama. Es por esto que Aaron He dijo es comentario:
fromCallable es un método conveniente para Observable.defer(() -> Observable.just(value))
Hace ese paso extra de crear un Observable usando .just . Si llama a una función de fromCallable que ya crea un Single, obtendrá un single anidado.
// Not very useful to get a Single<Single<*>> val fromCallable: Single<Single<String>> = Single.fromCallable { Single.just("Example") } // Better in these cases, where the function inside doesn't create a Single already: fun heavyFunction(): String { return "Heavy" } val fromCallable2: Single<String> = Single.fromCallable {heavyFunction()}Single.defer Single.defer llama a la función dentro de él, si devuelve un Single, entonces puede usar ese Single más adelante. Si no es así, no compilará.
val defer: Single<String> = Single.defer { Single.just("Example") } // This line won't compile: Single.defer {heavyFunction()} // You need to wrap it in a Single: val defer2: Single<String> = Single.defer {Single.just(heavyFunction())}Entonces, Single.fromCallable crea un Single a partir de un callable , de ahí el nombre. Este invocable que no tiene que crear un Single, puede ser cualquier cosa.
Defer no crea un nuevo Single, solo llama a su cuerpo que debería crear un Single. Es por eso que no tiene el from en el nombre de su función.