Rxjs 订阅包含TakeUntil的管道失败
我正在尝试使用RxJS编写一个Grafana插件。 将我的数据流传输到Grafana的每一个逻辑都是有效的,整个管道也是有效的 现在我需要停止流,以防任何选项被更改。 我在不同的博客帖子和文档中找到了 使用Rxjs 订阅包含TakeUntil的管道失败,rxjs,grafana,rxjs6,Rxjs,Grafana,Rxjs6,我正在尝试使用RxJS编写一个Grafana插件。 将我的数据流传输到Grafana的每一个逻辑都是有效的,整个管道也是有效的 现在我需要停止流,以防任何选项被更改。 我在不同的博客帖子和文档中找到了 使用takeUntil的建议 因此,当我想要中止流时,我创建了一个发出事件的可观察对象。但是现在任何订阅流的尝试都失败了,因为 您提供了一个无效的对象,其中需要流。您可以提供一个可观察的、承诺的、数组的或可观察的 只有引入takeUntil时,此问题才存在。这尤其奇怪,因为我使用的是TypeScr
takeUntil
的建议
因此,当我想要中止流时,我创建了一个发出事件的可观察对象。但是现在任何订阅流的尝试都失败了,因为
您提供了一个无效的对象,其中需要流。您可以提供一个可观察的、承诺的、数组的或可观察的
只有引入takeUntil时,此问题才存在。这尤其奇怪,因为我使用的是TypeScript,因此返回类型应该是安全的
为了调试这个问题,我粘贴了
问题依然存在。我检查了我安装的rxjs版本,并将其解析为6.5.3。我检查了rxjs的GitHub问题,但没有发现任何相关问题
我想问题出在我的环境中,最终我包括了我所有的依赖:
"dependencies": {
"@grafana/toolkit": "next",
"@grafana/ui": "latest",
"@types/grafana": "github:CorpGlory/types-grafana.git",
"@stomp/rx-stomp": "latest",
"rxjs-tslint-rules": "^4.25.0"
"sockjs-client": "^1.4.0",
"ts-loader": "^6.2.0",
"typescript": "^3.6.4"
}
我自己实现的片段
class LiveStreams {
private streams;
private stop$: Subject;
constructor() {
this.stop$ = new Subject<string>();
}
getStream(target): Observable<DataFrame[]> {
const stop_id = this.stop$.pipe(takeWhile(id => id == target.streamId));
stream = this.rxStomp.watch(target.streamName).pipe(
finalize(() => {
delete this.streams[target.streamId];
}),
map((message: IMessage) => {
let content = JSON.parse(message.body).content;
appendResponseToBufferedData(content, data);
return [data];
}),
throttleTime(target.throttleTime),
takeUntil(stop_id)
);
this.streams[target.streamId] = stream;
}
}
class-LiveStreams{
私人溪流;
私人电台$:主题;
构造函数(){
this.stop$=新主题();
}
getStream(目标):可观察{
const stop_id=this.stop$.pipe(takeWhile(id=>id==target.streamId));
stream=this.rxStomp.watch(target.streamName).pipe(
完成(()=>{
删除此.streams[target.streamId];
}),
映射((消息:IMessage)=>{
让content=JSON.parse(message.body).content;
appendResponseToBufferedData(内容、数据);
返回[数据];
}),
throttleTime(target.throttleTime),
takeUntil(停止id)
);
this.streams[target.streamId]=流;
}
}
如果您能提供有关我的环境的哪些部分的任何线索,我们将不胜感激。请尝试这种方法,它并不完整,也没有经过测试,但应该会给您一些提示:
private streams: Observable<any>[];
stopTriggers: Subject<boolean>[];
ngOnInit() {
this.getStream(123).subscribe(stream => {
// console.log(stream);
});
}
addStream(target) {
this.stopTriggers[target.streamId] = new Subject<boolean>();
const stream = of('something').pipe(
// finalize(() => {
// delete this.streams[target.streamId];
// }),
// map((message: IMessage) => {
// let content = JSON.parse(message.body).content;
// appendResponseToBufferedData(content, data);
// return [data];
// }),
// throttleTime(target.throttleTime),
takeUntil(this.stopTriggers[target.streamId])
);
this.streams[target.streamId] = stream;
}
getStream(id): Observable<any> {
return this.streams[id];
}
stopStream(id) {
this.stopTriggers[id].next();
this.stopTriggers[id].complete();
}
removeStream(id) {
this.streams.splice(id,1);
}
私有流:可观察[];
停止触发器:受试者[];
恩戈尼尼特(){
this.getStream(123).subscribe(stream=>{
//console.log(流);
});
}
addStream(目标){
this.stopTriggers[target.streamId]=新主题();
const stream=of('something')。管道(
//完成(()=>{
//删除此.streams[target.streamId];
// }),
//映射((消息:IMessage)=>{
//让content=JSON.parse(message.body).content;
//appendResponseToBufferedData(内容、数据);
//返回[数据];
// }),
//throttleTime(target.throttleTime),
takeUntil(this.stopTriggers[target.streamId])
);
this.streams[target.streamId]=流;
}
getStream(id):可观察{
返回这个.streams[id];
}
停止流(id){
this.stopTriggers[id].next();
this.stopTriggers[id].complete();
}
removeStream(id){
此.streams.splice(id,1);
}
我没有找到一个真正的答案,但我设法避免使用TakeUntil for Grafana
对于来这里参加格拉法纳的其他人:
如果请求不再匹配,Grafana会自动取消订阅。
因此,只需要删除流的自己的缓存版本
delete streams[streamId]
谢谢你的提问。我不知道错误的原因是什么。我希望有一个小例子能够调试您的例子,因为代码不是那么明显 我对解决这个问题的一条建议是在这个解决方案中更多地采用反应式方法。您可以使用您的选项创建一个observable,并使用
switchMap
操作符来解决您的问题。我认为从开发人员的角度来看,它将更具可读性和可维护性
我不知道你们班的要求。所以,不幸的是,我不能给你一个代码示例
祝你好运
请注意,如果您已经解决了此问题,请发布更新的。我想看看问题的原因。请提供更多代码。。我在任何地方都看不到你的作品…从文档中拿了错误的例子。更新为以获取更多代码以进行澄清。哪一行抛出错误?您拥有的似乎很好。
getStream(target):可观察的
不返回任何内容任何尝试订阅流都失败对于文档示例也是如此,最后一行失败。感谢您的尝试!错误仍然存在。正如我所说,我不应该关注我的特定代码,而应该关注环境。否则的话,我想文档示例应该已经起作用了。这是一个grafana数据源插件,不是一个完整的Angular应用程序。我想问题在于Grafana,而不是RXJS。可能是grafana发送了一个停止触发器,使管道在任何事情发生之前提前停止。我会关闭它,因为我无法在StackBlitz上复制它。不过,谢谢你抽出时间!
delete streams[streamId]