我正在寻找一种在流运算符之间跟踪值“路由”的方法。我的物化流在Notification对象(例如valueId
属性)上具有其他元数据。它的定义看起来像这样:
const x = stream.pipe(
materialize(),
map(x => Object.assign(x, {valueId: randomInt()}))
);
现在,我需要包装应用于x
的运算符。假设我需要使用map(x => x * 2)
,但是我不能这样做:
x.pipe(dematerialize(), map(x => x * 2))
因为我将丢失我的元数据。如何制作自动换行功能,该功能将适用于任何运算符,并且仍然保留我的其他元数据?
x.pipe(wrap(map(x => x * 2)))
我想到了这样的事情:
function wrap<T, R>(
operator: OperatorFunction<T, R>
): (source: Observable<TaggedValue<T>>) => Observable<TaggedValue<R>> {
return source =>
source.pipe(
switchMap(x =>
of(x).pipe(
dematerialize(),
operator,
materialize(),
map(z => Object.assign(z, { valueId: x.valueId }))
)
)
);
}
但是它会从of()
生成伪造的完整消息。
样本:https://stackblitz.com/edit/rxjs-fhv54p
答案 0 :(得分:1)
使用of
的方法中的问题在于,of
的完整通知已实现,并作为value
传递给source
的观察者。
尝试一下:
function wrap<T, R>(op: OperatorFunction<T, R>):
(source: Observable<any>) => Observable<any> {
return source => {
return source.pipe(
switchMap(x => of(x)
.pipe(
dematerialize(),
op,
map(y => ({value: y, uuid: x.uuid}))
)
),
materialize(),
map((x: any) => Object.assign(x, {
value: x.value ? x.value.value : undefined,
uuid: x.value ? x.value.uuid: undefined
})),
)
}
}
答案 1 :(得分:0)
您可以这样做
const stream$ = stream$.pipe(map((data=> ({...data, x: data.x + 1}))))
或将其移至自动换行功能
const mapProp = (propName, fn) => stream$.pipe(map((data=> ({...data, [propName]: fn(data[propName])}))))
//then
const stream$ = stream$.pipe(mapProp('x', x => x+1 ))
如果您想将其用于除map
const mapProp = (propName, fn) => stream$.pipe(
mergeMap(data =>
of(data[propName])
.pipe(
fn,
map(newPropValue => ({ ...data, propName: newPropValue })
)
)
)
//Usage
const stream$ = stream$.pipe(mapProp('x', map(x => x+1)))
答案 2 :(得分:0)
目前,我想到了使用包装功能状态“保留”数据的想法。尽管我到目前为止发现它是最安全的实现,但我并不真的喜欢它的“副作用”性质。
Dataset<B> dataset2
但是它不起作用,因为元数据被随机覆盖。