Эти два сценария различны, и они не должны работать одинаково.concat
принимает Observables в качестве аргументов, и он будет последовательно подписываться на эти потоки и подписываться на следующий Observable только после завершения предыдущего.Каждый оператор или метод создания возвращает Observable.Это означает, что в первом примере, когда вы используете concat
, он возвращает Observable, который испускает 20
, а затем 24
.Поскольку вы имеете дело с вложенным Observable, вы должны использовать mergeMap
, который подпишется на результирующее Observable, возвращаемое concat
.
Теперь во втором примере, если вы передадите массив, concat
преобразует это (используя from()
внутри) в Observable, который испускает 2 значения, и эти значения снова становятся Observables.Таким образом, у вас есть 3 уровня вложенности здесь.Первый - это самый внешний Observable, источник, который of(4)
, второй уровень - это тот, который вы отображаете внутри вашего mergeMap
, а третий во втором примере - это Observables внутри вашего массива.Дело в том, что вы выравниваете уровни только до уровня 2, но не до 3-го уровня.Опять же, во втором примере Observable, возвращаемое mergeMap
, испускает два Observable, но это только прокси, а не значения, испускаемые этими Observable.Если вы также хотите подписаться на них, вы можете подключиться к другому mergeMap
, например так:
concatArray() {
of(4)
.pipe(
mergeMap(number => concat([of(5 * number), of(6 * number)])),
mergeMap(x => x)
)
.subscribe(value => console.log(value));
}
Другой способ - распространить массив так, чтобы concat
не получалобъект, который ArrayLike
, а точнее Observables напрямую:
concatArray() {
of(4)
.pipe(
mergeMap(number => concat(...[of(5 * number), of(6 * number)]))
)
.subscribe(value => console.log(value));
}
Оба распечатают:
20
24
Я надеюсь, что это делает это немного более ясным и описывает различия междупервый и второй пример.