Promise.all zachowanie z RxJS Observables?


91

W Angular 1.x czasami musiałem składać wiele httpżądań i robić coś ze wszystkimi odpowiedziami. Wrzuciłbym wszystkie obietnice do tablicy i zadzwonił Promise.all(promises).then(function (results) {...}).

Najlepsze praktyki Angular 2 wydają się wskazywać na użycie RxJS Observablejako zamiennika obietnic w httpżądaniach. Jeśli mam dwa lub więcej różnych Observables utworzonych na podstawie żądań http, czy istnieje odpowiednik Promise.all()?

Odpowiedzi:


80

Bardziej prostą alternatywą emulacji Promise.alljest użycie forkJoinoperatora (uruchamia on wszystkie obserwable równolegle i łączy ich ostatnie elementy):

Trochę poza zakresem, ale na wypadek, gdyby to pomogło, w temacie łańcuchów obietnic, możesz użyć prostego flatMap: Por. RxJS Promise Composition (przekazywanie danych)


1
Czy jeśli mam 2 połączenia, jedną obietnicę zwrotu i inną możliwą do zaobserwowania, mogę użyć forkjoin? lub obietnica.all ()? czy nikt, muszę pozwolić, aby 2 funkcje zwracały ten sam typ obietnice lub obserwowalne?
Joe Sleiman,

1
Proszę o pomoc, forkJoin nie działa, gdy obserwable przekazane jako parametr nie emitują wartości. Mam void Observables i nadal chcę korzystać z funkcji forkJoin, ale nie działa
Goga Koreli

19

Zaktualizuj maj 2019 przy użyciu RxJs v6

Inne odpowiedzi okazały się przydatne i chciałem podać przykład odpowiedzi udzielonej przez Arnaud na temat zipużycia.

Oto fragment pokazujący równoważność między Promise.allrxjs a rxjs zip(zwróć także uwagę, w rxjs6, w jaki sposób zip jest teraz importowany przy użyciu "rxjs", a nie jako operatora).

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

Dane wyjściowe z obu są takie same. Uruchomienie powyższego daje:

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

Pracował dla mnie :)
Naveen Kumar V

12

forkJoin też działa dobrze, ale wolałbym kombajn najnowszy, ponieważ nie musisz się tym martwić, biorąc ostatnią wartość obserwabli. W ten sposób możesz być po prostu aktualizowany za każdym razem, gdy którykolwiek z nich również emituje nową wartość (np. Pobierasz w interwale lub coś takiego).


1
To nie odpowiada moim obecnym potrzebom, ale na pewno wkrótce z tego skorzystam.
Corey Ogburn

5
To nie zapewnia takiego samego zachowania jak Promise.all (), ale jest podobne do Promise.any ()
Purrell

Czy jeśli mam 2 połączenia, jedną obietnicę zwrotu i inną możliwą do zaobserwowania, mogę użyć forkjoin? lub obietnica.all ()? czy nikt, muszę pozwolić, aby 2 funkcje zwracały ten sam typ obietnice lub obserwowalne?
Joe Sleiman,

1
@JoeSleiman trochę spóźniony, ale możesz wybrać swoją stronę: Observable.fromPromise () razem z Observable.zip () lub Obserable.toPromise () z Promise.all ()
Arnaud P

11

Na widelcu reactivex.ioJoin wskazuje na Zip , który wykonał zadanie za mnie:

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

„oznacza to, że forkJoin nie wyemituje więcej niż raz i zakończy się po tym. Jeśli chcesz wyemitować połączone wartości nie tylko na koniec cyklu życia przekazanych obserwabli, ale także w trakcie jego trwania, wypróbuj zamiast tego funkcję connectLatest lub zip”. rxjs-dev.firebaseapp.com/api/index/function/forkJoin
Jeffrey Nicholson Carré

3
forkJoin czeka na zakończenie wszystkich obserwabli, podczas gdy zip emituje tablicę, gdy wszystkie dane wejściowe emitują pierwszą wartość. zip może emitować wiele razy. Jeśli masz wywołania http, nie ma to znaczenia.
hgoebl

Dobra, teraz rozumiem subtelność, wiwaty. Nie zdawałem sobie sprawy, że sekcje językowe się rozszerzają-_-
Arnaud P
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.