of([1,2,3]).pipe(concatAll()) 如何在 of([1,2,3]) 发出一个值时发出 3 个值?

How can of([1,2,3]).pipe(concatAll()) emit 3 values when of([1,2,3]) emits one?

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?

所有处理高阶可观察运算符的运算符,执行与 RxJS 的 from 运算符相同的转换。

即:

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

基本相同
mergeMap(_ => from([1,2,3]))

当 merging/switching/concatenating promises 和其他可迭代对象时,这同样有效。


您在行为中看到的差异还归因于以下事实:from 创建一个新的可观察对象,而高阶可观察对象运算符倾向于创建一个新的可观察对象 定义有关如何订阅这些可观察对象的行为。

所以 concatAll 正在添加额外的行为。


最后,对于给定的示例,仅仅因为两个事物具有相似的输出,并不意味着它们在幕后做同样的事情。

of([1,2,3]).pipe(concatAll())from([of(1),of(2),of(3)]).pipe(concatAll()) 描述了两组截然不同的行为,在(这种情况下)为您提供相同的控制台输出。

第一个发出一个数组,然后 concatAll() 将该数组转换为数字流。第二个发出三个 observable,并且仅当前一个完成时才让 concatAll() 订阅每个。他们只发出一个数字就完成了。

你可以通过你的第二个例子清楚地看出区别:

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

第一个发射和数组,第二个发射三个 observable。那没有改变。

concat([1,2,3]), &&
concat(of(1), of(2), of(3))

再次发出相同的输出。