在给定时间发出 API 请求以更新当前广播节目 Angular2 RxJS

Make API Request at a given time to update current radio show Angular2 RxJS

我正在为社区广播电台制定时间表,想知道如何更新当前正在播放的节目。

我已经知道每分钟轮询一次服务器(不确定这是要走的路,但它会在推送时工作),但看到我从 API 我想知道我是否可以将它设置为在结束时间过去后更新,然后设置一个具有下一个结束时间的新观察者。

有没有人知道我如何才能做到这一点,或者有更好的方法来更新当前节目?

我真正苦苦挣扎的是让我的头脑围绕 Observables 和 Subscribers。例如,如何从 radioShow$ 访问当前的 end_time 以查看它是否已传入 Observable.interval

对于这方面的任何帮助,我将不胜感激。

export class PlayerComponent {

    radioShow$ = new BehaviorSubject({
        start_time: new Date(),
        end_time: new Date(),
        radio_show: {
            id: 0,
            name: "Loading...",
    });

    constructor(
        @Inject('api') private api, 
        private http: Http) {
            Observable.interval(1000*60)
                .switchMap(() => http.get(api + '/schedule/current/show')
                .map(res => res.json()))
                .subscribe(this.radioShow$);
    }
}

查看player.component.html:

<div class="io-radio-player">
  <p class="schedule-times">{{(radioShow$ | async).start_time | date:"HH:mm"}}–{{(radioShow$ | async).end_time | date:"HH:mm"}}</p>
  <h3 class="margin-none">
    <a [routerLink]="['/radio-shows', (radioShow$ | async).radio_show.id]">{{(radioShow$ | async).radio_show.name | uppercase}}</a>
  </h3>
</div>

@martins 代码有效,但这是我最后使用的:

radioShow$ = new BehaviorSubject({
    start_time: new Date(),
    end_time: new Date(),
    radio_show: {
        id: 0,
        name: "Loading..."
    }
});
timer = new Subject();

@Component({
    selector: 'app-player',
    templateUrl: './player.component.html'
})
subject = new Subject();

    let request = http.get(api + '/schedule/current/show')
        .switchMap(() => http.get(api + '/schedule/current/show')
        .map(res => res.json()))
        .repeatWhen(() => this.subject)
        .publishReplay()
        .refCount();

    request
        .subscribe(this.radioShow$);

    request
        .map(response => { 
            // calculate the delay
            return Math.abs(new Date(response.end_time).getTime() - (new Date()).getTime());
        })
        .concatMap(delay => Observable.of(null).delay(delay))
        .subscribe(this.subject);

我认为您可以使用 repeatWhen() 运算符来完成此操作。您只需要使用一个额外的 Subject 来告诉它您何时要重复请求:

let subject = new Subject();

const response = {
  start_time: new Date(),
  end_time: new Date(),
  radio_show: {
    id: 0,
    name: "Loading..."
  }
};

let radioShow$ = Observable.defer(() => {
    // return http.get(...);
    return Observable.of(response);
  })
  .do(() => console.log('create new HTTP request'))
  .repeatWhen(() => subject)
  .publishReplay()
  .refCount();

// responses
radioShow$
  .startWith(response)
  .subscribe(val => console.log('Response:', val));

// pooling delay
radioShow$
  .map(response => { // calculate the delay
    // return response.end_time - (new Date()).getTime();
    return Math.random() * 1000;
  })
  .concatMap(delay => Observable.of(null).delay(delay))
  .subscribe(subject);

观看现场演示:https://jsbin.com/kutabiw/6/edit?js,console

这会在每次调用之间随机产生 0-3 秒的延迟,以模拟您通常计算延迟的位置。