Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 可观察<;可观察<;事件>;[]>;可观察<;事件>;[]_Javascript_Angular_Typescript_Rxjs - Fatal编程技术网

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解析为type
observable[]

您可以使用操作符
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 prop
newSubscription$
,当它发出时,来自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 prop
newSubscription$
,当它发出时,来自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
您不需要退订主题