Просто интересно, в чем разница между Observable.combineLatest
и Observable.forkJoin
? Насколько я понимаю, единственная разница заключается в том, forkJoin
что Observables должны быть завершены, а combineLatest
возвращать последние значения.
86
combineLatest()
иforkJoin()
функции , которые создают наблюдаемым. Они делают то же самое, но синтаксис отличается. Не путайте,combineLatest
откудаrxjs/operators
идет «конвейерный» оператор. Если вы импортируете не тот, то получите ошибки.Ответы:
Он не только
forkJoin
требует завершения всех входных наблюдаемых объектов, но также возвращает наблюдаемый объект, который производит одно значение, которое является массивом последних значений, созданных входными наблюдаемыми объектами. Другими словами, он ждет, пока завершится последний входной наблюдаемый объект, а затем выдает одно значение и завершается.Напротив,
combineLatest
возвращает Observable, который создает новое значение каждый раз, когда это делают входные наблюдаемые, после того как все входные наблюдаемые создали хотя бы одно значение. Это означает, что он может иметь бесконечное количество значений и может быть неполным. Это также означает, что входные наблюдаемые не должны завершаться перед созданием значения.источник
.catch()
,.onErrorResumeNext()
и, возможно.retry()
(если вызов Http может прерываться периодически).combineLatest()
, вы можете предоставить функцию проекции, чтобы указать, как создавать выходное значение из последних значений из входных наблюдаемых. По умолчанию, если вы его не укажете, вы получите массив последних сгенерированных значений.Также:
combLatest (...) последовательно запускает наблюдаемые объекты, один за другим
combineLatest
внутреннее использованиеconcat
, что означает, что значение должно быть получено для каждого наблюдаемого в массиве, прежде чем переходить к следующему.forkJoin (...) запускает наблюдаемые параллельно, в то же время
Если у вас есть 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
». Мне кажется, вы путаете объединение массивов с объединением RxJS. Последний действительно последовательно выполняет входные наблюдаемые, ожидая завершения каждого из них. Но это не используется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));
forkJoin - Когда все наблюдаемые завершены, испускает последнее переданное значение из каждого.
combLatest - когда какой-либо наблюдаемый излучает значение, испускает последнее значение из каждого.
Использование очень похоже, но вы не должны забывать отказаться от подписки на combLatest, в отличие от forkJoin .
источник