Просто интересно, в чем разница между Observable.combineLatest
и Observable.forkJoin
? Насколько я понимаю, единственная разница заключается в том, forkJoin
что Observables должны быть завершены, а 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
». Мне кажется, вы путаете объединение массивов с объединением 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 .
combineLatest()
иforkJoin()
функции , которые создают наблюдаемым. Они делают то же самое, но синтаксис отличается. Не путайте,combineLatest
откудаrxjs/operators
идет «конвейерный» оператор. Если вы импортируете не тот, то получите ошибки.