Javascript 可观察<;可观察<;事件>;[]>;可观察<;事件>;[]
我想创建一个函数,它合并从Javascript 可观察<;可观察<;事件>;[]>;可观察<;事件>;[],javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我想创建一个函数,它合并从数据通道数组创建的所有fromEvent,并发出将从其中任何一个通道接收的任何事件 这是初始功能: private dataChannels: BehaviorSubject<RTCDataChannel[]> = new BehaviorSubject([]); // datachannels array get filled at some point ... public on(): Observable<Event> {
数据通道数组创建的所有fromEvent
,并发出将从其中任何一个通道接收的任何事件
这是初始功能:
private dataChannels: BehaviorSubject<RTCDataChannel[]> = new BehaviorSubject([]);
// datachannels array get filled at some point
...
public on(): Observable<Event> {
const eventStreams = this.dataChannels.value.map((c) => fromEvent(c, 'message'));
return merge(...eventStreams);
}
这就是我的问题所在<代码>所有事件
属于可观察的类型。合并
将不接受的。如何将observable解析为typeobservable[]
?您可以使用操作符mergeAll
,如文档所述mergeAll订阅发出observable的observable。每次它观察到其中一个发出的内部可观测值时,它都会订阅该值,并在输出可观测值上传递来自内部可观测值的所有值。
并使用来自的操作符发出可观察数组中的每个可观察对象
constallevents=this.dataChannels.pipe(
map((channels)=>from(channels.map((c)=>fromEvent(c,'message')),
mergeAll();
);
您可以使用操作符mergeAll
,如文档所述mergeAll订阅一个发出可见光的可见光。每次它观察其中一个发出的内部可见光时,它订阅该可见光,并在输出可见光上传递来自内部可见光的所有值。
并使用来自
的操作符发出可观察数组中的每个可观察对象
constallevents=this.dataChannels.pipe(
map((channels)=>from(channels.map((c)=>fromEvent(c,'message')),
mergeAll();
);
您可以尝试合并在BehaviorSubject中接收到的所有观察对象。
我看到的问题是,即使从数据通道中删除了通道,也会挂起通道订阅。
我已经创建了一个classn propnewSubscription$
,当它发出时,来自event
的所有都将取消订阅
你可以试试这个解决方案
newSubscription$ = new Subject();
this.dataChannels.pipe(
tap(() => {
this.newSubscription$.next(); // kill existing subscriptions
this.newSubscription$ = new Subject(); // and wait for this for new ones
})
switchMap((allChannels) => {
const fromEvenObs = allChannels.map(c => fromEvent(c, 'message').pipe(takeUntil(newSubscription$)));
return merge(...fromEvenObs);
})).subscribe((data) => { // data from any event});
编辑:
由于我们使用的是switchMap()
,因此当dataChannels
接收新数据时,不需要有额外的可观察项来取消订阅事件
this.dataChannels.pipe(
switchMap((allChannels) => {
const fromEvenObs = allChannels.map(c => fromEvent(c, 'message'));
return merge(...fromEvenObs);
})).subscribe((data) => { //data from events });
您可以尝试合并在BehaviorSubject中接收到的所有观察对象。
我看到的问题是,即使从数据通道中删除了通道,也会挂起通道订阅。
我已经创建了一个classn propnewSubscription$
,当它发出时,来自event
的所有都将取消订阅
你可以试试这个解决方案
newSubscription$ = new Subject();
this.dataChannels.pipe(
tap(() => {
this.newSubscription$.next(); // kill existing subscriptions
this.newSubscription$ = new Subject(); // and wait for this for new ones
})
switchMap((allChannels) => {
const fromEvenObs = allChannels.map(c => fromEvent(c, 'message').pipe(takeUntil(newSubscription$)));
return merge(...fromEvenObs);
})).subscribe((data) => { // data from any event});
编辑:
由于我们使用的是switchMap()
,因此当dataChannels
接收新数据时,不需要有额外的可观察项来取消订阅事件
this.dataChannels.pipe(
switchMap((allChannels) => {
const fromEvenObs = allChannels.map(c => fromEvent(c, 'message'));
return merge(...fromEvenObs);
})).subscribe((data) => { //data from events });
为什么不订阅数据通道
?@VRoxa,因为该函数在角度服务中,将在其他地方调用/订阅。据我所知,您希望发出每个RTCDataChannel
“已接收”使用函数fromEvent
映射到,该函数将RTCDataChannel
作为第一个参数,加上'message'
,不是吗?@VRoxa Yes。然后,多个fromEvent
将开始接收事件,这些事件将通过订阅返回(订阅on
函数的人)为什么不订阅数据通道
?@VRoxa,因为该函数在角度服务中,将在其他地方调用/订阅。据我所知,您希望发出每个RTCDataChannel
“已接收”使用函数fromEvent
映射到,该函数将RTCDataChannel
作为第一个参数,加上'message'
,不是吗?@VRoxa Yes。然后,多个fromEvent
将开始接收事件,这些事件将通过订阅返回(订阅on
函数的人)这非常有效。我只需在fromEvent
的管道中添加映射((m)=>JSON.parse(m.data)
,即可接收正确的数据。@lars请检查我们是否确实需要额外的取消订阅主题,或者当我们使用开关映射时,所有内部观察值都会自动取消订阅(实际上应该取消订阅)当我调用this.dataChannels.next([]);
新事件/消息的接收似乎停止了(没有取消订阅主题)。@lars很酷,使用switchMap
你不需要取消订阅主题,这很好。我只需要添加map((m)=>JSON.parse(m.data)
在fromEvent
的管道中接收正确的数据。@lars请检查我们是否真的需要额外的取消订阅主题,或者当我调用this.dataChannels.next([])时,当我们使用开关映射时,所有内部观察值都会自动取消订阅(实际上应该取消订阅)
新事件/消息的接收似乎停止了(没有退订主题)。@lars cool then,使用switchMap
您不需要退订主题