Просто цікаво, в чому різниця між Observable.combineLatest
і Observable.forkJoin
? Наскільки я бачу, єдина відмінність полягає forkJoin
в тому, що спостережувані дані будуть завершені, а combineLatest
повернуті найновіші значення.
Відповіді:
Мало того, що forkJoin
потрібно, щоб усі вхідні спостережувані були заповнені, але він також повертає спостережуване, яке створює єдине значення, яке є масивом останніх значень, що створюються вхідними спостережуваними. Іншими словами, він чекає, поки останнє спостережуване введення не завершиться, а потім виробляє одне значення і завершує.
На відміну від цього, combineLatest
повертає Observable, який виробляє нове значення кожного разу, коли вхідні спостережувані роблять, як тільки всі вхідні спостережувані створюють принаймні одне значення. Це означає, що він міг мати нескінченні значення і не заповнювати. Це також означає, що вхідні спостережувані дані не потрібно заповнювати перед створенням значення.
.catch()
, .onErrorResumeNext()
і, можливо .retry()
(якщо виклик Http може періодично не спрацьовувати).
combineLatest()
, ви можете надати функцію проекції, щоб вказати, як виробляти вихідне значення з останніх значень із вхідних спостережуваних. За замовчуванням, якщо ви не вказали його, ви отримаєте масив останніх випущених значень.
Також:
combineLatest
внутрішньо використовує concat
, що означає, що значення має бути отримано для кожного спостережуваного в масиві перед переходом до наступного.
// 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)); };
Якщо у вас є 3 спостережувані джерела, і кожному з них потрібно 5 секунд для запуску, тоді для запуску знадобиться 15 секунд combineLatest
. Тоді як forkJoin
вони виконують паралельно, то це займе 5 секунд.
Тож forkJoin
працює дещо більше, як Promise.all(...)
там, де наказ не виконується.
Якщо помилка будь-якої з спостережуваних помилка - з combineLatest
наступними не буде виконана, але з forkJoin
усіма вони запущені. Тож combineLatest
може бути корисним виконати "послідовність" спостережуваних і зібрати результат разом.
Додаткова примітка: якщо спостережувані джерела вже `` запущені '' (передплачені чимось іншим), і ви використовуєте share
їх - тоді ви не побачите такої поведінки.
Ще більш досконала примітка: CombineLatest завжди надаватиме вам найсвіжіші дані з кожного джерела, тому, якщо одне із спостережуваних джерел видає кілька значень, ви отримаєте найновіше. Це не просто отримує одне значення для кожного джерела і переходить до наступного. Якщо вам потрібно переконатися, що ви отримуєте лише "наступний доступний елемент" для кожного спостережуваного джерела, ви можете додати .pipe(take(1))
його до джерела спостережуваного, додавши його до вхідного масиву.
concat()
в combineLatest()
коді роблять. Мені здається, що це Array.prototype.concat
метод, а не concat
метод RxJS . Припускаючи, що я маю рацію, тоді ця відповідь вводить в оману і неправильна, оскільки combineLatest()
не виконує спостережувані по черзі послідовно. Він виконує їх паралельно, як і forkJoin()
. Різниця полягає в тому, скільки значень вироблено і в тому, чи слід заповнити спостережувані джерела чи ні.
[source].concat(observables)
припускаючи, що це те, що ви мали на увазі, кажучи, що " combineLatest
внутрішньо використовує concat
". Мені здається, ви плутаєте масив concat з RxJS concat. Останній дійсно виконує вхідні спостережувані послідовно, чекаючи, поки кожен не буде завершений. Але цим не користується combineLatest()
, тобто цілком окремий оператор.
combineLatest()
і forkJoin()
обидва паралельно працюють. Запуск коду нижче дає близько 5000 для обох. 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));
forkПриєднуйтесь - Коли всі спостережувані завершені, значення з кожного.
об'єднатиОстанні - Коли будь-яке спостережуване випромінює значення, останнє значення від кожного.
Використання досить схоже, але не слід забувати скасувати підписку на combLatest на відміну від forkJoin .
combineLatest()
іforkJoin()
функції, які створюють спостережуване. Вони роблять те саме, але синтаксис різний. Не плутайте,combineLatest
зrxjs/operators
якого оператора "труби". Якщо ви імпортуєте неправильний, ви отримаєте помилки.