[英]rxjs observable changing interval
我有一個應該每 X 秒完成一個動作的可觀察對象。 X 的值動態變化。 我一直無法思考如何在運行時即時更改此間隔。 據我所知,我的想法的一個重大突破是 Observables 一旦被定義就不能改變,所以嘗試用新的間隔值重新定義 Observalbe 似乎不是正確的方法。
我一直在嘗試使用位於https://www.learnrxjs.io/operators/transformation/switchmap.html的代碼
到目前為止,我認為switchMap
至少是在正確的軌道上。 誰能提供一個例子或指出可能對我有幫助的資源?
至少,世界肯定需要更多的 RxJs 示例!
您可以使用Subject
以及switchMap
和interval
來動態控制周期。 每當主題發出一個值時,該值可用於指定間隔的周期:
const t = Date.now(); let subject = new Rx.Subject(); subject.switchMap(period => Rx.Observable.interval(period)).do(() => console.log('some action at time T+' + (Date.now() - t))).take(8).subscribe(); subject.next(50); setTimeout(() => subject.next(100), 200); setTimeout(() => subject.next(200), 400);
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>
添加一個工作示例來幫助 Google 員工
let startButton = document.getElementById('start'); let stopButton = document.getElementById('stop'); let updateButton = document.getElementById('update'); let i1 = document.getElementById('i1'); const start$ = Rx.Observable.fromEvent(startButton, 'click'); const stop$ = Rx.Observable.fromEvent(stopButton, 'click'); const update$ = Rx.Observable.fromEvent(updateButton, 'click') const period = () => (parseInt(i1.value)); Rx.Observable.merge( start$, update$, ).switchMap(() => { return Rx.Observable.interval(period()).takeUntil(stop$); }).subscribe(res => { console.log('here in the subscription:' + res); })
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script> <body> <button id="start">Start</button> <button id="stop">Stop</button> <button id="update">Update</button> <input id="i1" value=100></input> </body>
這是我使用 rxjs 6 的解決方案
import { interval, from } from 'rxjs';
import { map, take, concatAll, catchError, finalize } from 'rxjs/operators';
from([1,2,4,10])
.pipe(
// for each item, we create interval, and take the first element
map(x => timer(x * 1000)),
// concat all first elements
concatAll(),
// handle errors
catchError((error) => {
console.log('oops, something bad in pipe');
throw error;
}),
// finish retry
finalize(() => {
console.log('stop trying');
}),
)
// now subscribe and perform the actual retry
.subscribe(val => {
console.log('perform retry');
});
在此示例中,我嘗試在 1、2、4 和 10 秒后重新連接 4 次。
這是一個基於 RxJS 6 的優雅解決方案:
import { interval, BehaviorSubject } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
export class SomeComponent implements OnInit {
private interval$: BehaviorSubject<number> = new BehaviorSubject(10000);
ngOnInit() {
this.interval$.pipe(
//Assuming that the value provided by the input is in seconds
switchMap(value => interval(value * 1000)),
tap(() => this.doStuff())
)
.subscribe();
}
intervalChanged(value){
console.log(value);
this.interval$.next(value);
}
doStuff(){
console.log("Hi!");
}
}
模板:
<input (input)="intervalChanged($event.target.value)" type="number">
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.