[英]How to make an Observable collect values in the stream for x seconds before emitting to subscribes
背景:我需要在路由器NavigationStart
事件上運行一些代碼,但前提是它后面沒有NavigationCancel
。
我正在嘗試通過以下方式做到這一點:
const sourceTimer = timer(1000)
this.routerListenersSubscriber = this.router.events
.pipe(
map(e => e),
takeUntil(sourceTimer)
)
.subscribe(event => {...})
想要:很明顯,這一切都是在監聽路由器事件 50 毫秒。 我希望它在訂閱獲取它們之前從this.router.events
收集所有值 50 毫秒,以便我可以檢查NavigationCancel
事件是否發生。
編輯:我嘗試了很多東西,包括buffer
運算符的變體,但是這樣做時我遇到的問題是 stream 只會“運行”一次,然后在第一次之后不會再次運行后續事件“計時器”已用完。
這是您的問題的答案:
this.router.events
.pipe(
takeUntil(timer(50)),
toArray()
)
.subscribe(events => {
if(events.any(event => event instanceof NavigationCancel) return
else // do your code
})
選項1。
只需使用takeWhile
在NavigationCancel
上完成,以防止next
中的代碼運行。
this.router.events
.pipe(
map(x => x instanceof NavigationCancel ? throwError("NavigationCanceled") : x),
takeUntil(timer(50)),
)
.subscribe({
complete: () => {
// run your code here
},
error: console.error
})
選項 2。
this.router.events
.pipe(
every(x => !(x instanceof NavigationCancel)),
takeUntil(timer(50))
)
.subscribe(x => {
if (x == true)
{
// run your code
}
});
選項 3。
this.router.events.pipe( every(x =>,(x instanceof NavigationCancel)). takeUntil(timer(50)) );subscribe(x => { if (x == true) { // run your code } });
您可以使用 reduce 來收集發出的每個項目,然后使用 takeUntil 結束訂閱。 確保 takeUntil 在 reduce 之前。
const { timer } = rxjs; const { reduce, takeUntil } = rxjs.operators; timer(500, 500).pipe( takeUntil(timer(3000)), reduce((results, item) => [...results, item], []) ).subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.2/rxjs.umd.min.js" integrity="sha512-kN8bAZFoIra6Z7dDPNMD3efoGLn7QpOZgBcNpLwKIoBM5rXLVxt9nPHNo+4WrIsT0RBc/h2sXtN08n1ALxn4yw==" crossorigin="anonymous"></script>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.