簡體   English   中英

如何取消訂閱或取消可觀察到RxJS的大型數組的過濾?

[英]How can I unsubscribe or cancel the filtering of a large array that is an RxJS observable?

我的理解是,整個數組被推送給訂戶,這與可以取消訂閱/取消的間隔觀察器不同。

例如,以下取消有效...

 // emit a value every second for approx 10 seconds let obs = Rx.Observable.interval(1000) .take(10) let sub = obs.subscribe(console.log); // but cancel after approx 4 seconds setTimeout(() => { console.log('cancelling'); sub.unsubscribe() }, 4000); 
 <script src="https://unpkg.com/rxjs@5.5.10/bundles/Rx.min.js"></script> 

但是,用數組替換間隔不是。

 // emit a range let largeArray = [...Array(9999).keys()]; let obs = Rx.Observable.from(largeArray) let sub = obs.subscribe(console.log); // but cancel after approx 1ms setTimeout(() => { console.log('cancelling'); sub.unsubscribe() }, 1); // ... doesn't cancel 
 <script src="https://unpkg.com/rxjs@5.5.10/bundles/Rx.min.js"></script> 

是否需要以某種方式使每個元素異步,例如將其包裝在setTimeout(...,0)中? 也許我一直在盯着這個問題太久了,而我認為可以取消對數組的處理是完全不對的?

在數組上使用from(...)時,所有值將同步發出,這不允許任何執行時間授予要取消訂閱的setTimeout 實際上,它甚至在到達setTimeout的行之前就完成了發射。 要使發射不from(..., Rx.Scheduler.async)線程,您可以使用異步調度程序( from(..., Rx.Scheduler.async) ),它將使用setInterval調度工作。

這是文檔: https : //github.com/ReactiveX/rxjs/blob/master/doc/scheduler.md#scheduler-types

這是一個正在運行的示例。 我不得不將超時時間增加到100,以便有更多的呼吸空間。 這將減慢您的課程執行速度。 我不知道您嘗試此操作的原因。 如果您可以共享確切的用例,我們可能會提供一些更好的建議。

 // emit a range let largeArray = [...Array(9999).keys()]; let obs = Rx.Observable.from(largeArray, Rx.Scheduler.async); let sub = obs.subscribe(console.log); // but cancel after approx 1ms setTimeout(() => { console.log('cancelling'); sub.unsubscribe() }, 100); // ... doesn't cancel 
 <script src="https://unpkg.com/rxjs@5.5.10/bundles/Rx.min.js"></script> 

我已將@bygrace的答案標記為正確。 非常感激! 正如他對答案的評論中所述,我正在發布可觀察對象的自定義實現,該實現確實支持取消利息...

 const observable = stream => { let timerID; return { subscribe: observer => { timerID = setInterval(() => { if (stream.length === 0) { observer.complete(); clearInterval(timerID); timerID = undefined; } else { observer.next(stream.shift()); } }, 0); return { unsubscribe: () => { if (timerID) { clearInterval(timerID); timerID = undefined; observer.cancelled(); } } } } } } // will count to 9999 in the console ... let largeArray = [...Array(9999).keys()]; let obs = observable(largeArray); let sub = obs.subscribe({ next: a => console.log(a), cancelled: () => console.log('cancelled') }); // except I cancel it here setTimeout(sub.unsubscribe, 200); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM