Prometti tutti i comportamenti con gli osservabili RxJS?


90

In Angular 1.x a volte avrei bisogno di fare più httprichieste e fare qualcosa con tutte le risposte. Getterei tutte le promesse in una matrice e chiamerei Promise.all(promises).then(function (results) {...}).

Le migliori pratiche di Angular 2 sembrano indicare l'uso di RxJS Observablein sostituzione delle promesse nelle httprichieste. Se ho due o più osservabili diversi creati da richieste http, esiste un equivalente a Promise.all()?

Risposte:


80

L'alternativa più semplice per l'emulazione Promise.allè usare l' forkJoinoperatore (avvia tutte le osservabili in parallelo e unisce i loro ultimi elementi):

Un po 'fuori campo, ma nel caso in cui aiuti, in tema di concatenamento di promesse, puoi usare un semplice flatMap: Cfr. RxJS Promise Composition (passaggio di dati)


1
se ho 2 chiamate una promessa di reso e un'altra osservabile posso utilizzare forkjoin? o promise.all ()? o nessuno, devo lasciare che le 2 funzioni restituiscano lo stesso tipo promesse o osservabili?
Joe Sleiman

1
Per favore aiutatemi, forkJoin non funziona quando gli osservabili passati come parametri non emettono valori. Ho void Observables e desidero ancora utilizzare la funzionalità forkJoin ma non funziona
Goga Koreli

19

Aggiornamento maggio 2019 utilizzando RxJs v6

Ho trovato utili le altre risposte e ho voluto offrire un esempio per la risposta offerta da Arnaud zipsull'uso.

Ecco uno snippet che mostra l'equivalenza tra Promise.alle rxjs zip(nota anche, in rxjs6 come zip ora viene importato usando "rxjs" e non come operatore).

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);
});

L'output di entrambi è lo stesso. L'esecuzione di quanto sopra dà:

{ 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!' ]

Ha funzionato per me :)
Naveen Kumar V

12

Anche forkJoin funziona bene, ma preferisco combinareLatest poiché non devi preoccuparti che prenda l'ultimo valore di osservabili. In questo modo, puoi semplicemente essere aggiornato ogni volta che uno di essi emette un nuovo valore (ad esempio, recuperi su un intervallo o qualcosa del genere).


1
Questo non soddisfa le mie esigenze attuali, ma lo userò sicuramente presto.
Corey Ogburn,

5
Ciò non ottiene lo stesso comportamento di Promise.all (), ma è simile a Promise.any ()
Purrell

se ho 2 chiamate una promessa di reso e un'altra osservabile posso utilizzare forkjoin? o promise.all ()? o nessuno, devo lasciare che le 2 funzioni restituiscano lo stesso tipo promesse o osservabili?
Joe Sleiman

1
@JoeSleiman un po 'in ritardo, ma puoi scegliere da che parte stare : Observable.fromPromise () insieme a Observable.zip () , o Obserable.toPromise () con Promise.all ()
Arnaud P

11

Su reattivex.io forkJoin in realtà punta a Zip , che ha fatto il lavoro per me:

let subscription = Observable.zip(obs1, obs2, ...).subscribe(...);

"questo significa che forkJoin non emetterà più di una volta e verrà completato dopo di che. Se hai bisogno di emettere valori combinati non solo alla fine del ciclo di vita delle osservabili passate, ma anche durante tutto questo, prova invece combinationLatest o zip." rxjs-dev.firebaseapp.com/api/index/function/forkJoin
Jeffrey Nicholson Carré

3
forkJoin attende che tutte le osservabili finiscano, mentre zip emette un array quando tutti gli input emettono il loro primo valore. zip potrebbe essere emesso molte volte. Se hai chiamate http, non fa differenza.
hgoebl

Bene, ora capisco la sottigliezza, applausi. Non mi ero reso conto che le sezioni linguistiche si espandono-_-
Arnaud P
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.