Zastanawiam się tylko, jakie są różnice między Observable.combineLatest
i Observable.forkJoin
? O ile widzę, jedyną różnicą jest to, forkJoin
że oczekuje się, że Observables zostaną zakończone, a combineLatest
zwrócą najnowsze wartości.
Odpowiedzi:
Nie tylko forkJoin
wymaga uzupełnienia wszystkich obserwowalnych wejściowych, ale także zwraca obserwowalną, która generuje pojedynczą wartość, która jest tablicą ostatnich wartości utworzonych przez obserwable wejściowe. Innymi słowy, czeka, aż ostatnie obserwowalne dane wejściowe zostaną zakończone, a następnie wygeneruje pojedynczą wartość i zakończy.
W przeciwieństwie do tego combineLatest
zwraca Observable, który tworzy nową wartość za każdym razem, gdy robią to obserwable wejściowe, gdy wszystkie obserwable wejściowe dały co najmniej jedną wartość. Oznacza to, że może mieć nieskończone wartości i może się nie kończyć. Oznacza to również, że obserwable wejściowe nie muszą kończyć się przed utworzeniem wartości.
.catch()
, .onErrorResumeNext()
i prawdopodobnie .retry()
(jeśli wywołanie HTTP może sporadycznie kończyć się niepowodzeniem).
combineLatest()
można podać funkcję projekcji, aby określić, w jaki sposób utworzyć wartość wyjściową na podstawie najnowszych wartości z danych wejściowych. Domyślnie, jeśli nie określisz żadnego, otrzymasz tablicę ostatnich wyemitowanych wartości.
Również:
combineLatest
używa wewnętrznie concat
, co oznacza, że wartość musi zostać uzyskana dla każdego obserwowalnego w tablicy przed przejściem do następnej.
// 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)); };
Jeśli masz 3 obserwowalne źródła, a każde z nich trwa 5 sekund, uruchomienie zajmie 15 sekund combineLatest
. Podczas forkJoin
gdy działają równolegle, więc zajmie to 5 sekund.
forkJoin
Działa więc trochę bardziej jak Promise.all(...)
tam, gdzie nakaz nie jest egzekwowany.
Jeśli którykolwiek z obserwabli się nie powiedzie - combineLatest
kolejne nie zostaną wykonane, ale forkJoin
wszystkie działają. combineLatest
Może więc być przydatne do wykonania „sekwencji” obserwabli i zebrania wszystkich wyników.
Uwaga dla zaawansowanych: Jeśli obserwable źródłowe są już „uruchomione” (subskrybowane przez coś innego) i używasz share
na nich - nie zobaczysz tego zachowania.
Jeszcze bardziej zaawansowana uwaga: CombineLatest zawsze podaje najnowsze dane z każdego źródła, więc jeśli jeden z obserwowalnych źródeł emituje wiele wartości, otrzymasz najnowsze. Nie tylko pobiera jedną wartość dla każdego źródła i przechodzi do następnego. Jeśli chcesz mieć pewność, że otrzymujesz tylko „następny dostępny element” dla każdego obserwowalnego źródła, możesz dodać .pipe(take(1))
go do źródła obserwowalnego, gdy dodajesz je do tablicy wejściowej.
concat()
w combineLatest()
kodzie. Wydaje mi się, że to Array.prototype.concat
metoda, a nie concat
metoda RxJS . Zakładając, że mam rację, odpowiedź ta jest myląca i niepoprawna, ponieważ combineLatest()
nie wykonuje obserwacji po kolei. Wykonuje je równolegle, tak samo jak forkJoin()
. Różnica polega na tym, ile wartości jest generowanych i czy obserwable źródłowe muszą się zakończyć, czy nie.
[source].concat(observables)
zakładając, że właśnie to miałeś na myśli, mówiąc, że „ combineLatest
używa wewnętrznie concat
”. Wydaje mi się, że mylisz konkatowanie tablic z konkatacją RxJS. Ta ostatnia rzeczywiście wykonuje obserwowalne wejściowe po kolei, czekając, aż każda z nich zostanie ukończona. Ale to nie jest używane przez combineLatest()
, to jest całkowicie oddzielny operator.
combineLatest()
i forkJoin()
obie działają równolegle. Uruchomienie poniższego kodu daje około 5000 dla obu. const start = new Date().getTime();
combineLatest([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin - Po zakończeniu wszystkich obserwabli, wyemituj ostatnią wyemitowaną wartość z każdego.
connectLatest - gdy jakikolwiek obserwowalny emituje wartość, emituje najnowszą wartość z każdego.
Sposób użycia jest dość podobny, ale nie należy zapominać o wypisaniu się z funkcji CombineLatest w przeciwieństwie do forkJoin .
combineLatest()
iforkJoin()
funkcje, które tworzą obserwowalne. Robią to samo, ale składnia jest inna. Nie należy mylić,combineLatest
odrxjs/operators
którego jest operatorem „potokowalnym”. Jeśli zaimportujesz niewłaściwy, otrzymasz błędy.