Как может of([1,2,3]).pipe(concatAll()) выдавать 3 значения, когда of([1,2,3]) выдает одно?

#rxjs #rxjs6 #rxjs-observables #rxjs-pipeable-operators

#rxjs #rxjs6 #rxjs-наблюдаемые #rxjs-конвейерные операторы

Вопрос:

 of([1,2,3]).subscribe(console.log)
 

С принтами: [1,2,3]

Но:

 of([1,2,3]).pipe(concatAll()).subscribe(console.log)
 

С принтами:

 1
2
3
 

Почему это происходит?Почему добавление concatAll() выдает элементы массива один за другим? Разве это не противоположно тому, что означает слово concat?

Я чувствую, что concatAll() это действует по-разному в зависимости от ввода.

Рассмотрим также это:

 from([of(1),of(2),of(3)]).pipe(concatAll()).subscribe(console.log)
 

Он снова напечатает:

 1
2
3
 

Итак of([1,2,3]).pipe(concatAll()) == from([of(1),of(2),of(3)]).pipe(concatAll())

Но of([1,2,3]) != from([of(1),of(2),of(3)]) потому что подписка на последнее приведет к печати:

 Observable { _isScalar: false, _subscribe: [Function] }
Observable { _isScalar: false, _subscribe: [Function] }
Observable { _isScalar: false, _subscribe: [Function] }
 

Правая часть приведенного выше равенства мне довольно понятна, но где задокументировано, что concatAll() все значения массива должны выдаваться отдельно, действуя как конвейерное from ?

Ответ №1:

Все операторы, которые имеют дело с наблюдаемыми операторами более высокого порядка, выполняют то же преобразование, что from и оператор RxJS.

то есть:

 mergeMap(_ => ([1,2,3]))
 

В основном совпадает с

 mergeMap(_ => from([1,2,3]))
 

Это работает так же при объединении / переключении / объединении обещаний и других итераций.


Разница, которую вы видите в поведении, также объясняется тем фактом, что from создается новая наблюдаемая, в то время как наблюдаемые операторы более высокого порядка, как правило, создают новые наблюдаемые и определяют поведение в зависимости от того, на что подписаны эти наблюдаемые.

как concatAll и добавление дополнительного поведения.


Наконец, только потому, что две вещи имеют похожие результаты для данного примера, не означает, что они делают одно и то же под капотом.

of([1,2,3]).pipe(concatAll()) и from([of(1),of(2),of(3)]).pipe(concatAll()) опишите два очень разных набора поведений, которые в данном случае дают вам один и тот же вывод на консоль.

Первое выдает массив, и этот массив превращается в поток чисел concatAll() . Второй генерирует три наблюдаемых объекта и имеет функцию concatAll(), подписывающуюся на каждый из них только после завершения предыдущего. Они завершаются после ввода всего одного числа.

Вы можете ясно увидеть различие на вашем втором примере:

of([1,2,3]) и from([of(1),of(2),of(3)])

Первый испускает и массив, второй испускает три наблюдаемых. Это не изменилось.

 concat([1,2,3]), amp;amp;
concat(of(1), of(2), of(3))
 

Также снова выдайте тот же результат.

Комментарии:

1. Где в документации указано, что все наблюдаемые операторы более высокого порядка выполняют это from преобразование?

2. @Sebi2020 Посмотрите здесь: rxjs.dev/api/operators/switchMap обратите внимание, как проект выдает ObservableInput<any> ? Затем посмотрите rxjs.dev/api/index/type-alias/ObservableInput, что это значит. Также посмотрите здесь: rxjs.dev/api/index/function/from , чтобы увидеть, что from происходит то же самое.