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.
86
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.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.źródło
.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ż:
connectLatest (...) uruchamia obserable po kolei, jeden po drugim
combineLatest
używa wewnętrznieconcat
, co oznacza, że wartość musi zostać uzyskana dla każdego obserwowalnego w tablicy przed przejściem do następnej.forkJoin (...) uruchamia obserwable równolegle, w tym samym czasie
Jeśli masz 3 obserwowalne źródła, a każde z nich trwa 5 sekund, uruchomienie zajmie 15 sekund
combineLatest
. PodczasforkJoin
gdy działają równolegle, więc zajmie to 5 sekund.forkJoin
Działa więc trochę bardziej jakPromise.all(...)
tam, gdzie nakaz nie jest egzekwowany.Uwagi dotyczące obsługi błędów:
Jeśli którykolwiek z obserwabli się nie powiedzie -
combineLatest
kolejne nie zostaną wykonane, aleforkJoin
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.źródło
concat()
wcombineLatest()
kodzie. Wydaje mi się, że toArray.prototype.concat
metoda, a nieconcat
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 jakforkJoin()
. 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ętrznieconcat
”. 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 przezcombineLatest()
, to jest całkowicie oddzielny operator.combineLatest()
iforkJoin()
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 .
źródło