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
可观察对象正在侦听Firebasechild_添加的
事件,因此当这些冷可观察对象从没有订户变为有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应该做什么。你让我走上了正确的道路。我很快就会给出一个简单的解决方案。