我有一个函数,我正在调用Manager
的{{1}}实例,我正在订阅它以更新我的应用程序的状态(我正在管理一个状态服务器端也是如此。
问题在于onSpecificData()
的{{1}}实现我使用SomeManager
运算符合并了3个不同的onSpecificData()
运算符,由于某种原因触发了调用所有潜在的Observable
运算符中的运算符,即使只有一个源是发出值的运算符
SomeManager.ts
merge()
Manager.ts
Observable
SomeDriver.ts
export class DerivedManager implements Manager {
private driver: SomeDriver;
constructor(...) {
this.driver = new SomeDriver(...);
}
public onSpecificData(): Observable<DataType> {
return merge(
this.driver.onSpecificData(Sources.Source1).map((value) => {
return {source1: value};
}),
this.driver.onSpecificData(Sources.Source2).map((value) => {
return {source2: value};
}),
this.driver.onSpecificData(Sources.Source3).map((value) => {
return {source3: value};
})
);
}
Driver.ts
export type DataType = Partial<{value1: number, value2: number, value3: number}>;
export interface Manager {
onSpecificData(): Observable<DataType>;
}
Handler.ts
export const enum Sources {
Source1,
Source2,
Source3,
}
export class SomeDriver extends Driver {
private static specificDataId = 1337; // some number
private handler: Handler;
constructor(...) {
super(...);
this.handler = new Handler(this.connection, ...);
// ...
}
// ...
onSpecificData(source: Sources): Observable<number> {
return this.handler
.listenToData<SpecificDataType>(
SomeDriver.specificDataId,
(data) => data.source === source)
).map((data) => data.value);
}
}
最后,export abstract class Driver {
protected connection: Duplex;
constructor(...) {
// init connection, etc...
}
public abstract onSpecificData(source: number);
// some implementations and more abstract stuff...
}
- ing:
export class Handler {
private data$: Observable<Buffer>;
constructor(private connection: Duplex, ...) {
this.data$ = Observable.fromEvent<Buffer>(connection as any, 'data');
}
listenToData<T>(dataId: number, filter?: (data: T) => boolean) {
return this.data$
.map((data) => {
// decode and transform
})
.filter((decodedData) => !decodedData.error && decodedData.value.id)
.do((decodedData) => {
console.log(`Got ${decodedData.value.id}`);
})
.map((decodedData) => decodedData.value.value as T)
.filter(filter || () => true);
}
}
正如您所看到的,只有 1 基础subscribe()
(export default function(store: Store<State>, manager: Manager) {
// ...
manager.onSpecificData()
.subscribe((data) => {
// update state according to returned data
});
}
),但显然Observable
中的运算符链被调用 3 < / strong>次为其发出的每个值。我已经知道这是因为data$
{3} listenToData<T>()
中的SomeManager#onSpecificData()
,但我不知道为什么会这样。我希望每个值都调用一次。
非常感谢帮助。
答案 0 :(得分:0)
我在&#34; hacky&#34;中解决了这个问题。在我看来,方式。我将data$
替换为Subject
,从stream
'data'
事件中创建了一个observable,将所有共享逻辑移动到该observable并从中发出一个值主题,像这样:
export class Handler {
private dataSrc = new Subject<DecodedData>();
constructor(private connection: Duplex, ...) {
Observable.fromEvent<Buffer>(connection as any, 'data')
.map((data) => {
// decode and transform
})
.filter((decodedData) => !decodedData.error)
.do((decodedData) => {
console.log(`Got ${decodedData.value.id}`);
})
.subscribe((decodedData) => {
this.dataSrc.next(decodedData);
});
}
listenToData<T>(dataId: number, filter?: (data: T) => boolean) {
return this.dataSrc
.filter((decodedData) => decodedData.value.id === dataId)
.map((decodedData) => decodedData.value.value as T)
.filter(filter || () => true);
}
}
不完全是我正在寻找的解决方案,但它确实有效。如果有人有更好的解决方案,更适合&#34; Rx方式&#34;要做的事情,我很乐意听到它。