Me pregunto cuáles son las diferencias entre Observable.combineLatest
y Observable.forkJoin
. Por lo que puedo ver, la única diferencia es que forkJoin
espera que los Observables se completen, mientras combineLatest
devuelve los últimos valores.
84
combineLatest()
yforkJoin()
que crean un observable. Hacen lo mismo, pero la sintaxis es diferente. No confundacombineLatest
derxjs/operators
cuál es un operador 'pipeable'. Si importa el incorrecto, obtendrá errores.Respuestas:
No solo
forkJoin
requiere que se completen todos los observables de entrada, sino que también devuelve un observable que produce un valor único que es una matriz de los últimos valores producidos por los observables de entrada. En otras palabras, espera hasta que se complete la última entrada observable, y luego produce un valor único y se completa.Por el contrario,
combineLatest
devuelve un Observable que produce un nuevo valor cada vez que lo hacen los observables de entrada, una vez que todos los observables de entrada han producido al menos un valor. Esto significa que podría tener valores infinitos y es posible que no esté completo. También significa que los observables de entrada no tienen que completarse antes de producir un valor.fuente
.catch()
,.onErrorResumeNext()
y posiblemente.retry()
(si la llamada Http puede fallar de forma intermitente).combineLatest()
, puede proporcionar una función de proyección para especificar cómo producir un valor de salida a partir de los últimos valores de los observables de entrada. De forma predeterminada, si no especifica uno, obtendrá una matriz de los últimos valores emitidos.También:
combineLatest (...) ejecuta observables en secuencia, uno por uno
combineLatest
utiliza internamenteconcat
, lo que significa que se debe obtener un valor para cada observable en la matriz antes de pasar al siguiente.forkJoin (...) ejecuta observables en paralelo, al mismo tiempo
Si tiene 3 observables de origen, y cada uno de ellos tarda 5 segundos en ejecutarse, entonces tardará 15 segundos
combineLatest
en ejecutarse. MientrasforkJoin
que se ejecutan en paralelo, tomará 5 segundos.Por lo
forkJoin
tanto, funciona más bienPromise.all(...)
cuando la orden no se aplica.Consideración para el manejo de errores:
Si alguno de los errores observables sale,
combineLatest
los siguientes no se ejecutarán, peroforkJoin
todos se están ejecutando. Por tanto,combineLatest
puede ser útil ejecutar una 'secuencia' de observables y recopilar el resultado en su conjunto.Nota avanzada: si los observables de origen ya se están 'ejecutando' (suscritos por algo más) y los está usando
share
, entonces no verá este comportamiento.Nota aún más avanzada: CombineLatest siempre le dará lo último de cada fuente, por lo que si uno de los observables de la fuente emite varios valores, obtendrá el último. No solo obtiene un valor único para cada fuente y pasa a la siguiente. Si necesita asegurarse de obtener solo el 'próximo elemento disponible' para cada fuente observable, puede agregar
.pipe(take(1))
a la fuente observable a medida que lo agrega a la matriz de entrada.fuente
concat()
en elcombineLatest()
código. Me parece que es elArray.prototype.concat
método, no elconcat
método RxJS . Suponiendo que tenga razón, entonces esta respuesta es engañosa e incorrecta, yacombineLatest()
que no ejecuta los observables uno por uno, en secuencia. Los ejecuta en paralelo, igual queforkJoin()
. La diferencia está en cuántos valores se producen y si los observables de origen deben completarse o no.[source].concat(observables)
asumiendo que eso es lo que quisiste decir cuando dijiste que "combineLatest
utiliza internamenteconcat
". Me parece que está confundiendo array concat con RxJS concat. Este último de hecho ejecuta los observables de entrada en secuencia, esperando hasta que cada uno esté completo. Pero eso no es usado porcombineLatest()
, es un operador completamente separado.combineLatest()
yforkJoin()
ambos corren en paralelo. Ejecutar el siguiente código genera alrededor de 5000 para ambos.const start = new Date().getTime();
combineLatest([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin : cuando se completen todos los observables, emite el último valor emitido de cada uno.
combineLatest : cuando cualquier observable emite un valor, emite el último valor de cada uno.
El uso es bastante similar, pero no debes olvidar darte de baja de combineLatest a diferencia de forkJoin .
fuente