如何解决如果从switchmap返回仍可观察的订阅,订阅是否可以保持订阅
请考虑以下内容:
a$ = someObservable$.pipe(
switchMap(data => liveForEver$)
);
a$.subscribe();
a$.unsubscribe();
现在,顾名思义,liveForEver $已由代码的其他部分订阅。可能会因为switchMap返回一个“活动的”可观察值而导致a $取消订阅后a $仍保持订阅状态吗?
解决方法
定义运算符后,通常具有取消订阅子订阅的行为。如果您创建了一个自定义运算符,但未能执行此操作,则可能会导致内存泄漏。考虑以下自定义运算符:
function timesTwo(input$: Observable<number>): Observable<number> {
return new Observable<number>(observer => {
input$.subscribe({
next: val => observer.next(val * 2),complete: () => observer.complete(),error: err => observer.error()
});
return {
// I should $input.unsubscribe()
unsubscribe: () => {/*Do Nothing*/}
}
});
}
function timesTwoPipeable<T>(): MonoTypeOperatorFunction<T> {
return input$ => timesTwo(input$);
}
在这里,我创建了自己的自定义rxjs运算符,该运算符将输入流乘以2。所以1:
const subscription = interval(1000).pipe(map(x => x * 2))
.subscribe(console.log);
setTimeout(() => subscription.unsubscribe(),5000);
和2:
const subscription = timesTwo(interval(1000))
.subscribe(console.log);
setTimeout(() => subscription.unsubscribe(),5000);
和3:
const subscription = interval(1000).pipe(timesTwoPipeable())
.subscribe(console.log);
setTimeout(() => subscription.unsubscribe(),5000);
所有控制台都具有相同的输出,但是2和3都订阅间隔流,然后不取消订阅该间隔流。因此,后两个悄悄地造成内存泄漏。您可以通过在所有三个示例中将interval(1000)
更改为interval(1000).pipe(tap(_ => console.log("Still Alive")))
来自己进行测试。
所有内置的RxJS运算符都会自行清理。如果您自己构建,请确保执行相同操作!
我在您的问题中注意到的一件事情是您尝试取消订阅可观察的对象。我很惊讶没有创建错误。
我的理解是:
a$.subscribe();
a$.unsubscribe();
应为:
const sub = a$.subscribe();
sub.unsubscribe();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。