web-dev-qa-db-fra.com

Promise.all comportement avec RxJS Observables?

Dans Angular 1.x, je devais parfois faire plusieurs demandes http et faire quelque chose avec toutes les réponses. Je mettais toutes les promesses dans un tableau et j'appellerais Promise.all(promises).then(function (results) {...}).

Les meilleures pratiques concernant Angular 2 semblent indiquer l'utilisation de Observable de RxJS en remplacement des promesses dans les requêtes http. Si j'ai plusieurs observables différents créés à partir de requêtes http, leur équivalent à Promise.all()?

67
Corey Ogburn

L'alternative la plus simple pour émuler Promise.all est d'utiliser l'opérateur forkJoin (il commence toutes les observables en parallèle et joint leurs derniers éléments):

Un peu en dehors de la portée, mais au cas où cela aiderait, au sujet du chaînage des promesses, vous pouvez utiliser un simple flatMap: Cf. Composition de promesse RxJS (transmission de données)

66
user3743222

forkJoin fonctionne très bien aussi, mais je préférerais combineLatest puisque vous n'avez pas à vous soucier de la prise de la dernière valeur observable. De cette façon, vous pouvez simplement obtenir une mise à jour chaque fois que l'un d'entre eux émet également une nouvelle valeur (par exemple, vous récupérez un intervalle ou quelque chose).

12
kakigoori

Sur reactivex.io forkJoin pointe en fait sur Zip , qui a fait le travail pour moi:

let subscription = Observable.Zip(obs1, obs2, ...).subscribe(...);
11
Arnaud P

Mise à jour de mai 2019 à l'aide de RxJs v6

Les autres réponses ont été utiles et souhaitaient donner un exemple de la réponse proposée par Arnaud à propos de Zip usage.

Voici un extrait montrant l'équivalence entre Promise.all et le rxjs Zip (notez également, dans rxjs6, comment Zip est maintenant importé à l’aide de "rxjs" et non en tant qu’opérateur).

import { Zip } from "rxjs";

const the_weather = new Promise(resolve => {
  setTimeout(() => {
    resolve({ temp: 29, conditions: "Sunny with Clouds" });
  }, 2000);
});

const the_tweets = new Promise(resolve => {
  setTimeout(() => {
    resolve(["I like cake", "BBQ is good too!"]);
  }, 500);
});

// Using RxJs
let source$ = Zip(the_weather, the_tweets);
source$.subscribe(([weatherInfo, tweetInfo]) =>
  console.log(weatherInfo, tweetInfo)
);

// Using ES6 Promises
Promise.all([the_weather, the_tweets]).then(responses => {
  const [weatherInfo, tweetInfo] = responses;
  console.log(weatherInfo, tweetInfo);
});

La sortie des deux est la même. Exécuter ce qui précède donne:

{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]
{ temp: 29, conditions: 'Sunny with Clouds' } [ 'I like cake', 'BBQ is good too!' ]
6
arcseldon