How to get an observable to return data immediately and every 5 seconds thereafter

♀尐吖头ヾ 提交于 2019-11-26 11:21:01

问题


I want to create an observable that returns data from a webapi. I\'d like it to return the data immediately, and poll the API every 10 seconds. The code below shows I\'m using the \'interval\' method. But this delays the first set of data by 10 seconds. How do I get that first flush of data to come down with no initial delay?

export class EventService {
    public events$: Observable<Event[]>;
    private _eventsObserver: Observer<Event[]>;
    private pollInterval: number = 5000;

    private _dataStore: {
        events: Event[];
    };

    constructor(private http: Http) {
        this._dataStore = { events: [] };

        this.events$ = new Observable(observer => this._eventsObserver = observer)
            .startWith(this._dataStore.events)
            .share();
    }

    pollEvents() {
        return Observable.interval(10000)
            .switchMap(() => {
                return this.http.get(\'app/resources/data/scheduleevents.json\')
                    .map((responseData) => {
                        return responseData.json();
                    });
            })
            .map((events: Array<any>) => {
                let result: Array<Event> = [];
                if (events[\"data\"]) {
                    events[\"data\"].forEach((event) => {
                        result.push(event);
                    });
                }
                return result;
            });
    }
}

回答1:


Got it:

        .interval(5000)
        .startWith(0);



回答2:


Use timer. I think the timer is what you need (see RxJS tab): http://reactivex.io/documentation/operators/timer.html#collapseRxJS

Could be used like:

Observable.timer(0, 5000).flatMap(() => apiCall())

Where 0 - delay before emitting the first value, 5000 - emit value after each 5s




回答3:


    let timer = TimerObservable.create(0, 5000);
    this.sub = timer.subscribe(t => {
        this.yourMethod()
    });

To unsubscribe run this.sub.unsubscribe()




回答4:


I personnally use interval with startWith (need RxJs 6+), here is a complete example:

   history: any;
   historySubscription: Subscription;

   constructor(private jobService: JobService) { }

   ngOnInit() {

      this.historySubscription = interval(10000).pipe(
         startWith(0),
         flatMap(() => this.jobService.getHistory())
      ).subscribe(data => {
         this.history = data;
      });

   }

   ngOnDestroy() {
      this.historySubscription.unsubscribe();
   }

This retrieves history on init and then every 10 seconds.

Another alternative is using timer as explained by @Alendorff.




回答5:


For angualr2 below is the code i have written in my application and it is working as expected -

In service --

import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';

getList(): Observable<IVM> {
    return Observable.interval(5000).startWith(0)
          .switchMap(() => 
             this._http.get(this._vmURL )
                 .map((response: Response) => <IVM>response.json().data)
                 .do(data => console.log('All: ' + JSON.stringify(data)))
                .catch(this.handleError)
             );
}

In component --

private getInstanceDetails(): void {
    this._vmDataService.getList()
        .subscribe(vmList => {
           //Do whatever you want with the vmList here :) 
        },
        error => this.errorMessage = <any>error);
}

Thanks, Kindly let me know your thoughts.




回答6:


Observable.interval(5L, TimeUnit.SECONDS)
        .startWith(0)
        .observeOn(AndroidSchedulers.mainThread())
        .map { foobar() }

works fine for me. Thanks



来源:https://stackoverflow.com/questions/36612945/how-to-get-an-observable-to-return-data-immediately-and-every-5-seconds-thereaft

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!