Rxjs switchMap中动态数组的组合测试是不断取消订阅和重新订阅

Rxjs switchMap中动态数组的组合测试是不断取消订阅和重新订阅,rxjs,Rxjs,我至少有两个按钮,我想动态收听点击ListingArray$将发出我需要监听的按钮的数组(ar)。当有人点击我正在收听的其中一个按钮时,我需要控制台记录被点击的按钮,并记录时间间隔中的值 如果ar从[1,2]变为[1],我们需要停止收听对按钮2的点击。因此,需要为2删除DOM click事件,这将触发.finally()操作符。但是对于1,我们应该保持订阅状态,并且.finally()中的代码不应该运行,因为没有任何内容被取消订阅 const obj$ = {}; Rx.Observable.

我至少有两个按钮,我想动态收听点击
ListingArray$
将发出我需要监听的按钮的数组(
ar
)。当有人点击我正在收听的其中一个按钮时,我需要控制台记录被点击的按钮,并记录时间间隔中的值

如果
ar
[1,2]
变为
[1]
,我们需要停止收听对按钮2的点击。因此,需要为
2
删除DOM click事件,这将触发
.finally()
操作符。但是对于
1
,我们应该保持订阅状态,并且
.finally()
中的代码不应该运行,因为没有任何内容被取消订阅

const obj$ = {};

Rx.Observable.combineLatest(
  Rx.Observable.interval(2000),
  listeningArray$ // Will randomly emit either [1] or [1,2]
)
.switchMap(([x, ar]) => {
    const observables = [];

    ar.forEach(n => {
        let nEl = document.getElementById('el'+n);

        obj$[n] = obj$[n] || Rx.Observable.fromEvent(nEl, 'click')
          .map(()=>{
            console.log(' el' + n);
          })
          .finally(() => {
            console.log(' FINALLY_' + n);
          });

        observables.push(obj$[n]);
    })

    return Rx.Observable.combineLatest(...observables);
})
.subscribe()
但是,每次间隔发出一个值时,DOM事件都会被删除,然后立即再次添加,并且.finally操作符中的代码会运行
1
2

这真让我沮丧。我错过了什么


这是一个有点复杂的情况,所以我创建了这个:

FRP中的状态是不可变的。因此,当您切换到第二个发射时,包含
[1,2]
的前一个可观察的
CombineTest
将被取消订阅,并调用最后一个操作符。在订阅仅包含
[1]

如果您只想取消订阅一个按钮,您可以将状态存储在DOM中(将atr添加到按钮),并使用
filter
忽略按钮。
或者你可以在每个按钮上添加一个
TakeWhile()
,指示何时应该取消订阅,这样它就可以调用自己的
最终()

我实际上非常接近,但我误解了
开关映射的意义

switchMap
设计用于在从上面发出新值时取消订阅它返回的可观察值。这就是为什么当需要发出新请求时,它可以用来取消旧的挂起Http请求

我遇到的问题是意料之中的
switchMap
将在订阅当前observable之前取消订阅先前返回的observable。正如我在问题中解释的那样,这是不可接受的。这是不可接受的原因,因为在我的实际项目中,
fromEvent
可观察对象正在侦听Firebase
child_添加的
事件,因此当这些冷可观察对象从没有订户变为有1个订户时,Firebase随后会为每个已经存在的子对象触发事件,以及对未来的补充

我使用了
mergeMap
一段时间,但手动取消订阅以前返回的观测值确实很困难,而且有问题

因此,我在
switchMap
执行
unsubscribe from old=>subscribe to new
的过程时,为内部观察添加了一个订阅者,以便始终有一个订阅者。我使用了
takeUntil(Observable.timer(0))
来确保订户没有建立并导致内存泄漏

也许有更好的办法,但这是我找到的最好的办法

const obj$={};
Rx.可观察的(
Rx.可观测间隔(2000),
ListingArray$//将随机发出[1]或[1,2]
)
.switchMap(([x,ar])=>{
常量可观测值=[];
ar.forEach(n=>{
设nEl=document.getElementById('el'+n);
obj$[n]=obj$[n]| | Rx.Observable.fromEvent(nEl,'点击')
.map(()=>{
控制台日志('el'+n);
})
.最后(()=>{
log('FINALLY_'+n);
})
.share();
obj$[n].takeUntil(Rx.Observable.timer(0))
.subscribe();
可观测推(obj$[n]);
})
返回Rx.Observable.combineLatest(…Observable);
})

.subscribe()
尝试更好地描述您正在寻找的行为。@MarkvanStraten谢谢您的提示。我重新组织了我的问题。希望更清楚。嘿,谢谢你的回答。我误解了switchMap应该做什么。你让我走上了正确的道路。我很快就会给出一个简单的解决方案。