我很难理解与在concat
运算符中使用mergeMap
函数有关的内容。
concat
的文档中说
您可以传递一个Observable数组,也可以将它们直接作为参数。
当我直接将Observables用作参数时,如以下示例所示,我在控制台中正确获得了20和24。
of(4)
.pipe(
mergeMap(number => concat(of(5 * number), of(6 * number)))
)
.subscribe(value => console.log(value));
但是当我将它们放置为数组时,在控制台中,我得到的是Observables而不是它们的值:
of(4)
.pipe(
mergeMap(number => concat([of(5 * number), of(6 * number)]))
)
.subscribe(value => console.log(value));
这是Stackblitz中的live version。
有人知道为什么吗?这两个示例不应该完全一样吗?
答案 0 :(得分:1)
这两种情况是不同的,它们不应完全相同。 concat
将Observables作为参数,它将顺序地订阅这些流,并且仅在前一个Observable完成时订阅下一个Observable。每个运算符或创建方法都返回一个Observable。这意味着在第一个示例中,当您使用concat
时,它将返回一个Observable,该对象发出20
,然后发出24
。因为您要处理嵌套的Observable,所以必须使用mergeMap
,它将订阅concat
返回的结果Observable。
现在在第二个示例中,如果您传递一个数组,concat
会将其(内部使用from()
转换为一个发出2个值的Observable,然后这些值再次成为Observables。因此,这里有3个嵌套级别。第一个是最外部的Observable,它是源of(4)
,第二个层次是您在mergeMap
内部映射到的层次,第二个示例中的第三个层次是数组内部的Observables。问题是您只能将级别展平到2级,而不能展平到3级。同样,在您的第二个示例中,mergeMap
返回的Observable发出两个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
而是直接可观察到的对象:
concatArray() {
of(4)
.pipe(
mergeMap(number => concat(...[of(5 * number), of(6 * number)]))
)
.subscribe(value => console.log(value));
}
两者都会打印出来:
20
24
我希望这可以使这一点更加清楚,并描述第一个示例和第二个示例之间的区别。