Rxjs 通过展平/取消展平操作可观察阵列,同时保持流

Rxjs 通过展平/取消展平操作可观察阵列,同时保持流,rxjs,Rxjs,Q:RxJs操作符是否可以用来展平数组、转换项目,然后将其取消展平,同时保持连续流(未完成)? 对于此处的简化示例: 如果遵循以下方法: mergeMap(next => next), switchMap(next => of(***transforming logic***)), toArray() 然后,可观察的不完整,值也没有通过。可以添加take(1),但这是一个连续流 如果使用: mergeMap(next => next), switchMap(next =>

Q:RxJs操作符是否可以用来展平数组、转换项目,然后将其取消展平,同时保持连续流(未完成)?

对于此处的简化示例:

如果遵循以下方法:

mergeMap(next => next),
switchMap(next => of(***transforming logic***)),
toArray()
然后,可观察的不完整,值也没有通过。可以添加
take(1)
,但这是一个连续流

如果使用:

mergeMap(next => next),
switchMap(next => of(***transforming logic***)),
scan()
那么这个效果很好。但是,每次源可观测物发射时,累加器都不会重置,因此打算将值累加回数组的
scan()
最终将每个过程中的多个数组组合在一起。蓄能器可以复位吗

显然,可以通过以下方式实现:

switchMap(next => of(next.map(***transforming logic***)))

但我的现实世界的例子远比这复杂得多,而且与NgRx有关。

这里有一种方法:

mergeMap(next => next),
switchMap(next => of(***transforming logic***)),
toArray()
src$.pipe(
合并地图(
arr=>from(arr)
.烟斗(
开关映射(项=>/*…*/),
toArray(),
)
)
)

对于每个发射的阵列,
mergeMap
将创建一个内部可观测(
from(..)
)。在那里,
from(array)
将分别发出每个项目,允许您在
switchMap
中执行一些逻辑。最后附加
toArray()
将为您提供一个数组,其中包含
switchMap
的内部可观察结果。

您不需要在此处使用
mergeMap
switchMap
。只有在异步执行某些操作时,才需要这些。例如,如果您正在获取输入值并创建一个可观察对象(例如:进行http调用)

通过在
mergeMap
的内部使用
of
,您基本上是从一个
可观察的
开始,获取未打包的值(一个
数组
),然后将其转换回一个
可观察的

从你的堆栈闪电战:

第一个策略没有完成的原因是
toArray()
发生在源代码级别(
单击ToArrayButton
),而这永远不会完成

如果确实需要,可以将其嵌套到一个级别,以便
toArray()
发生在数组的级别上(使用
from()
创建,将在发出所有值后完成)

但是。。。我们真的不需要使用
from
来创建一个可观察对象,这样它就可以完成,这样
toArray()
就可以为您重新组合它。我们可以使用常规的
map
操作符,而不是
mergeMap
,以及
Array.map()

这是可行的,但不一定要充分利用RxJS操作符吗

好吧,你必须用正确的工具做正确的工作!在本例中,您只需转换数组元素,因此
array.map()
非常适合这种情况

但我的现实例子比这复杂得多

如果您担心代码变得混乱,可以将转换逻辑分解为它自己的函数:

const transformedMaleNames = maleNames.pipe(
  map(next => next.map(transformName))
);

function transformName(next) {
  const parts = next.name.split(' ');
  return { firstName: parts[0], lastName: parts[1] };
}

这是一个有效的方法。

我认为
switchMap
应该是
map
@BizzyBob如果
switchMap
的回调没有返回可观察的,那么是的,它应该是
map
。在本例中,我假设将有一些异步操作。
const transformedMaleNames = maleNames.pipe(
  map(next => next.map(transformName))
);

function transformName(next) {
  const parts = next.name.split(' ');
  return { firstName: parts[0], lastName: parts[1] };
}