在 mergeMap 中使用 concat
Using concat inside mergeMap
我很难理解与使用 concat
function inside a mergeMap
运算符相关的内容。
concat
的文档说
You can pass either an array of Observables, or put them directly as arguments.
当我将 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。
知道这是为什么吗?两个例子不应该一样工作吗?
这两种情况不同,它们的工作方式应该不同。 concat
将 Observable 作为参数,它将顺序订阅这些流,并且仅在前一个 Observable 完成时订阅下一个 Observable。每个运算符或创建方法 return 都是一个 Observable。这意味着在第一个例子中,当你使用 concat
时,它会 return 一个发出 20
然后 24
的 Observable。因为您正在处理一个嵌套的 Observable,所以您必须使用 mergeMap
,它将订阅由 concat
.
生成的结果 Observable return
现在在第二个例子中,如果你传入一个数组,concat
会将它(在内部使用 from()
)转换为一个 Observable,它发出 2 个值,这些值又是 Observable。所以你在这里有 3 层嵌套。第一个是最外层的 Observable,源,of(4)
,第二个层次是你映射到你的 mergeMap
里面的那个,第二个例子中的第三个是你数组里面的 Observables。问题是你只能将级别展平到第 2 级而不是第 3 级。同样,在您的第二个示例中,由 mergeMap
编辑的 Observable return 发出两个 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
我希望这能让它更清楚一点,并描述第一个和第二个示例之间的区别。
我很难理解与使用 concat
function inside a mergeMap
运算符相关的内容。
concat
的文档说
You can pass either an array of Observables, or put them directly as arguments.
当我将 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。
知道这是为什么吗?两个例子不应该一样工作吗?
这两种情况不同,它们的工作方式应该不同。 concat
将 Observable 作为参数,它将顺序订阅这些流,并且仅在前一个 Observable 完成时订阅下一个 Observable。每个运算符或创建方法 return 都是一个 Observable。这意味着在第一个例子中,当你使用 concat
时,它会 return 一个发出 20
然后 24
的 Observable。因为您正在处理一个嵌套的 Observable,所以您必须使用 mergeMap
,它将订阅由 concat
.
现在在第二个例子中,如果你传入一个数组,concat
会将它(在内部使用 from()
)转换为一个 Observable,它发出 2 个值,这些值又是 Observable。所以你在这里有 3 层嵌套。第一个是最外层的 Observable,源,of(4)
,第二个层次是你映射到你的 mergeMap
里面的那个,第二个例子中的第三个是你数组里面的 Observables。问题是你只能将级别展平到第 2 级而不是第 3 级。同样,在您的第二个示例中,由 mergeMap
编辑的 Observable return 发出两个 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
我希望这能让它更清楚一点,并描述第一个和第二个示例之间的区别。