简体   繁体   English

使用Rxjs的`takeUntil`自动退订-无需等待发射?

[英]Using Rxjs's `takeUntil` to auto unsubscribe - without waiting for emission?

I've already read Ben's article regarding unsubscribing via , takeUntil , takeWhile ( the predicate version ) 我已经阅读了Ben的有关通过, takeUntiltakeWhile取消订阅的文章谓词版本

I've used it like this example in my Angular app 我已经在Angular应用中像这个例子一样使用它

But there is something which I don't understand. 但是有些事情我不理解。

Say I have an Observable which emit values after a long time : 假设我有一个Observable,它在很长一段时间后会发出值:

const source = Rx.Observable.interval(10000);

var isContinue=true;

const example = source.takeWhile(val => isContinue)
                      .subscribe(val => {},()=>{},()=>console.log('complete'));

setTimeout(function (){isContinue=false},3000) //somewhere in destructor

Well , this will show "complete" only after 10 seconds and not after 3. 好吧,这只会在10秒后而不是3秒后显示“完成”。

So basically if I have a component which subscribes to an Observable and that observable doesn't emit values for a long time , it will still have a reference to my object , causing slow memory leaks. 因此,基本上,如果我有一个订阅了Observable的组件,并且observable长时间不发出值,它仍然会引用我的对象,从而导致内存泄漏缓慢。

Question: 题:

How can I use the takeWhile operator to unsubscribe as soon as I set the isContinue value. 设置isContinue值后,如何使用takeWhile运算符取消订阅。

I don't want to trust a service which may not emit values and to keep a reference to my component. 我不想信任可能不会发出值的服务并保留对我的组件的引用。

JSBIN JSBIN

I believe your code produces the correct emissions - but your concern is the timeliness of the completion (it should complete after 3 seconds, not 10 seconds). 我相信您的代码会产生正确的排放-但是您所关心的是完成的及时性(应该在3秒而不是10秒后完成)。

It takes 10 seconds as takeWhile only tests its predicate when the source observable emits. takeWhile仅在可观察到的源发出时测试其谓词时,它花费10秒。

takeUntil will fix this, but it needs an observable to wait on: takeUntil将解决此问题,但需要观察一下才能等待:

const source = Rx.Observable.interval(10000);

const abort = new Subject();

const example = source.takeUntil(abort)
                      .subscribe(val=>{}, ()=>{}, ()=>console.log('complete'));

setTimeout(function () {abort.next()}, 3000) //somewhere in destructor

您需要将isContinue变量设置为Observable并订阅两个observables: sourceisContinue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM