如何取消订阅@Output作为Observable

时间:2018-03-15 12:55:19

标签: angular rxjs rxjs5

我有一个关于在Angular中取消订阅let data = [{ "email": "srjahir32@gmail.com" }, { "email": "srjahir32@gmail.com" }, { "email": "srjahir32@gmail.com" }, { "email": "g.anshul@gmail.com" }, { "email": "bspilak@cooperequipment.ca" }, { "email": "g.anshul@gmail.com" } ] function groupBy(list, keyGetter) { const map = new Map(); list.forEach((item) => { const key = keyGetter(item); if (!map.has(key)) { map.set(key, [item]); } else { map.get(key).push(item); } }); return map; } var grouped = groupBy(data, a => a.email); console.log(grouped);的问题。我知道EventEmitter会自动清理,但上次我需要使用Output作为我的Observable。我的意思是,我想让Output每秒发出一次最大事件。所以我的代码看起来像:

Output

好的,它工作得很好 - 我想。唯一的问题是取消订阅。我在StackOverflow上找到one solution,但我仍然不确定,我该怎么做才能正确。就我而言:

@Output() loadNextEvent: Observable<any>;
loadNextSubject = new Subject();

constructor(private el: ElementRef) {
    this.loadNextEvent = this.loadNextSubject.asObservable()
        .throttleTime(1000); // once per second
    }

emit() {
    this.loadNextSubject.next('new event');
}

问题: 这是@Output() loadNextEvent: Observable<any>; loadNextSubject = new Subject(); constructor(private el: ElementRef) { this.loadNextEvent = this.loadNextSubject.asObservable() .takeUntil(this.loadNextSubject) //does it make any sense? .throttleTime(1000); // once per second } emit() { this.loadNextSubject.next('new event'); } ngOnDestroy() { this.loadNextSubject.complete(); } 的正确取消订阅吗? observable Output有道理吗?或者.takeUntil(this.loadNextSubject)可能.asObservable()确保在Subject完成时清理了Observable?有人知道我的问题的答案吗?或者,有一个更好的解决方案,然后使用Observable作为Output,我的情况?

1 个答案:

答案 0 :(得分:2)

如果您想使用takeUntil,则通知程序Observable需要发出next通知,而不仅仅是完成通知。所以正确的方法是这样的:

ngOnDestroy() {
    this.loadNextSubject.next();
    this.loadNextSubject.complete();
}

在这种情况下,您也不需要使用asObservable()。主题是Observables所以使用asObservable()只会用另一个Observable包装它,这是不必要的。

还有一件事。在Angular 5中,当使用EventEmitter链接运算符时,会产生内存泄漏的错误(链没有正确处理)。有关详细信息,请查看https://github.com/angular/angular/issues/21999

此处已修复https://github.com/angular/angular/pull/22016,自Angular 6以来应该可以使用。

我认为这正是你现在正在做的事情。一种简单的方法可以避免这种情况,直到Angular 6在添加任何运算符之前实际使用asObservable()(请参阅此注释https://github.com/angular/angular/issues/21999#issuecomment-362921475)。