angular v 6.1.10
打字稿v 2.9.2
rxjs v 6.3.3
ng2-stmompjs v 7.0.0
我将ng2-stomp library用于创建可观察到的Web套接字,这将启动可观察到的订阅。根据我的要求,我正在基于应用程序ID创建多个频道订阅,现在想一次订阅所有这些频道,或者我们可以说可以观察到更高阶,因此尝试使用各种rxjs运算符merge
,{{1} },mergeAll
,但到目前为止没有任何效果。这是我到目前为止所做的。
现在这个正在工作
concat
但是我认为我们可以将所有可观测的东西合而为一,并且可以全部订阅。请注意,我无法使用appList = [{appID: '123'}, {appID: '345'}];
const appList$ = appList.map((appID: string, idx: number) => {
const headers = Object.assign({}, this.headers, { id: `app_${idx}` });
const watcher = this.rxStompService.watch(`/topic/${appID}`, headers);
console.log({ watcher }); // This is observable
return watcher;
});
appList$.forEach((app$) => {
app$.subscribe((message: Message) => {
const notification: Notification = JSON.parse(message.body);
this.totalNotificationCount++;
if (Object.keys(notification).length) {
this.notificationMessages.push(notification);
}
});
});
{
"watcher": { "_isScalar": false, "source": { "source": { "_isScalar": false } }, "operator": { "connectable": { "source": { "_isScalar": false } } } }
}
,因为appList是动态的,因此WebSocket的数量是动态的。以下是我将多个可观察对象转换为一次的方法。
ForkJoin
和concat
运算符map
这会导致错误:
类型“ MonoTypeOperatorFunction”上不存在属性“管道”。
const batch = appList.map((appID, idx) => {
console.log({ appID, idx });
const headers = Object.assign({}, this.headers, { id: `app_${idx}` });
const watcher = this.rxStompService.watch(`/topic/${appID}`, headers);
return watcher;
});
concat(...batch).pipe( map (i => i)).subscribe({ });
之后使用全部订阅concat
错误:类型'MonoTypeOperatorFunction'上不存在属性'subscribe'。
concat(...batch).subscribe({
next: (v: any) => console.log(v),
complete: () => console.log('Complete')
});
pipe
const appList$ = appList.map((appID: string, idx: number) => {
const headers = Object.assign({}, this.headers, { id: `app_${idx}` });
const watcher = this.rxStompService.watch(`/topic/${appID}`, headers);
return watcher;
});
console.log({ appList$ });
appList$.pipe(
takeUntil(this.ngUnsubscribe),
tap((i) => {
console.log('tapping', i);
})
);
错误:类型'Observable []'不存在属性'pipe'
所以我的问题是如何将所有可观察者合并为一次并订阅一次
答案 0 :(得分:1)
这太神奇了;每当我在这里写下问题并重试时,我自己找到了解决方案。
我已经使用from
和mergeMap
解决了这种方法,感谢this angular in depth article
private watchApplications(appList: string[]) {
const appList$ = from(appList).pipe(
mergeMap((appID, idx) => {
const headers = Object.assign({}, this.headers, { id: `app_${idx}` });
const watcher = this.rxStompService.watch(`/topic/${appID}`, headers);
return watcher;
})
);
appList$
.pipe(
takeUntil(this.ngUnsubscribe),
tap((f: Frame) => {
console.log('tapping Frame', f);
})
)
.subscribe((message: Message) => {
const notification: Notification = JSON.parse(message.body);
console.log({ notification });
this.totalNotificationCount++;
if (Object.keys(notification).length) {
this.notificationMessages.push(notification);
}
});
}