簡體   English   中英

rxjs 可觀察到的變化間隔

[英]rxjs observable changing interval

我有一個應該每 X 秒完成一個動作的可觀察對象。 X 的值動態變化。 我一直無法思考如何在運行時即時更改此間隔。 據我所知,我的想法的一個重大突破是 Observables 一旦被定義就不能改變,所以嘗試用新的間隔值重新定義 Observalbe 似乎不是正確的方法。

我一直在嘗試使用位於https://www.learnrxjs.io/operators/transformation/switchmap.html的代碼

到目前為止,我認為switchMap至少是在正確的軌道上。 誰能提供一個例子或指出可能對我有幫助的資源?

至少,世界肯定需要更多的 RxJs 示例!

您可以使用Subject以及switchMapinterval來動態控制周期。 每當主題發出一個值時,該值可用於指定間隔的周期:

 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.

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