Zastanawiam się tylko, jakie są różnice między Observable.combineLatesti Observable.forkJoin? O ile widzę, jedyną różnicą jest to, forkJoinże oczekuje się, że Observables zostaną zakończone, a combineLatestzwrócą najnowsze wartości.
Odpowiedzi:
Nie tylko forkJoinwymaga 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 combineLatestzwraca 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ż:
combineLatestuż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 forkJoingdy działają równolegle, więc zajmie to 5 sekund.
forkJoinDziała więc trochę bardziej jak Promise.all(...)tam, gdzie nakaz nie jest egzekwowany.
Jeśli którykolwiek z obserwabli się nie powiedzie - combineLatestkolejne nie zostaną wykonane, ale forkJoinwszystkie działają. combineLatestMoż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 sharena 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.concatmetoda, a nie concatmetoda 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 „ combineLatestuż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ć,combineLatestodrxjs/operatorsktórego jest operatorem „potokowalnym”. Jeśli zaimportujesz niewłaściwy, otrzymasz błędy.