Просто цікаво, в чому різниця між 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якого оператора "труби". Якщо ви імпортуєте неправильний, ви отримаєте помилки.