web-dev-qa-db-fra.com

Rxjs: Observable.combineLatest vs Observable.forkJoin

Demandez-vous quelles sont les différences entre Observable.combineLatest et Observable.forkJoin? Autant que je sache, la seule différence est que forkJoin s'attend à ce que les observables soient terminés, tandis que combineLatest renvoie les dernières valeurs.

52
Tuong Le

Non seulement forkJoin nécessite l'achèvement de tous les observables en entrée, mais il retourne également un observable qui produit une valeur unique représentant un tableau des dernières valeurs produites par les observables en entrée. En d'autres termes, il attend que la dernière entrée observable soit terminée, puis produit une valeur unique et se termine.

En revanche, combineLatest renvoie un observable qui produit une nouvelle valeur chaque fois que les observables en entrée le font, une fois que tous les observables en entrée ont généré au moins une valeur. Cela signifie qu'il pourrait avoir des valeurs infinies et ne pas être complet. Cela signifie également que les observables en entrée ne doivent pas nécessairement être terminés avant de générer une valeur.

88
GregL

Également:

combineLatest (...) exécute les observables en séquence, un par un

combineLatest utilise en interne concat, ce qui signifie qu'une valeur doit être obtenue pour chaque observable du tableau avant de passer au suivant.

// partial source of static combineLatest (uses the rxjs/operators combineLatest internally):
// If you're using TypeScript then the output array will be strongly typed based on type inference
return function (source) { return source.lift.call(from_1.from([source].concat(observables)), 
                           new combineLatest_1.CombineLatestOperator(project)); };

forkJoin (...) exécute des observables en parallèle, en même temps

Si vous avez 3 observables sources et qu'elles prennent chacune 5 secondes pour s'exécuter, il faudra 15 secondes pour que combineLatest s'exécute. Alors que forkJoin, ils s’exécutent en parallèle, ce qui prendra 5 secondes.

Ainsi, forkJoin fonctionne un peu plus comme Promise.all(...) où l'ordre n'est pas appliqué.

Prise en compte de la gestion des erreurs:

Si l'une des erreurs observables sort - avec combineLatest, les suivantes ne seront pas exécutées, mais avec forkJoin, elles seront toutes en cours d'exécution. Ainsi, combineLatest peut être utile pour exécuter une "séquence" d'observables et collecter le résultat.


Remarque avancée: Si les observables source sont déjà en cours d'exécution (abonnées à quelque chose d'autre) et que vous utilisez share dessus, vous ne verrez pas ce comportement.

Note encore plus avancée: CombineLatest vous fournira toujours la dernière en date de chaque source. Ainsi, si l’un des observables de la source émet plusieurs valeurs, vous obtiendrez la dernière. Il ne s'agit pas simplement d'obtenir une valeur unique pour chaque source et de passer à la suivante. Si vous devez vous assurer que vous n'obtenez que le "prochain élément disponible" pour chaque source observable, vous pouvez ajouter .pipe(take(1)) à la source observable à mesure que vous l'ajoutez au tableau d'entrée.

8
Simon_Weaver

forkJoin - Lorsque tous les éléments observables sont terminés, émettez la dernière valeur émise par chacun.

combineLatest - Lorsqu'un observable émet une valeur, émet la dernière valeur de chaque.

L'utilisation est assez similaire, mais vous ne devez pas oublier de vous désabonner combineLatest contrairement à forkJoin.

1
Dmitry Grinko