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()
?
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)
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).
Sur reactivex.io forkJoin pointe en fait sur Zip , qui a fait le travail pour moi:
let subscription = Observable.Zip(obs1, obs2, ...).subscribe(...);
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!' ]