2017-02-20 3 views
2

Я работаю над расписанием для радиостанции сообщества и задаюсь вопросом, как я могу обновить текущую показную игру.Сделайте запрос API в заданное время для обновления текущего радиошоу Angular2 RxJS

У меня есть опрос сервера один раз в минуту (не уверен, что это путь, но он будет работать при нажатии), но, видя, что у меня есть время от API, я задавался вопросом, Я могу настроить его для обновления по истечении времени окончания, а затем настроить новый наблюдатель со следующим временем окончания.

Есть ли у кого-нибудь идеи, как я мог бы это сделать, или у вас есть лучший способ приблизиться к обновлению текущего шоу?

То, с чем я действительно борюсь, получает мою голову вокруг наблюдателей и подписчиков. Как я могу получить доступ к текущему end_time от radioShow$, чтобы узнать, прошел ли он в 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); 

ответ

1

Я думаю, что вы могли бы сделать это с оператором 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-3s задержки между каждым вызовом для имитации, где вы обычно вычисляете задержку.

+0

Большое вам спасибо за ваш ответ, похоже, меня гораздо ближе к решению. Мне пришлось переработать его для Angular2 https://plnkr.co/edit/vzSXA6vItalQVTQNvzN9. Вы знакомы с BehaviourSubjects? Поскольку я хотел бы поддерживать 'radioShow $' как единый. Я также не уверен, где 'http.get()' будет вписываться в это. Извиняюсь, если это боль, я очень новый и RxJS и Angular2. – Sarcoma

+0

@Sarcoma Я немного обновил свой ответ. Вы можете увидеть, куда идет 'http.get (...)'. Я также добавил '.publishReplay(). RefCount()' и '.do()', чтобы убедиться, что мы не делаем больше запросов, чем необходимо. Почему вам нужно использовать 'BehaviorSubject'? На самом деле это не идеально в этой ситуации, потому что 'repeatWhen()' отписывает и подписывается на свой источник Observable. Мы использовали 'BehaviorSubject', чем мы всегда получали значение по умолчанию. Я предполагаю, что вы должны не использовать 'BehaviorSubject' вообще. – martin

+0

Еще раз спасибо, я еще раз посмотрю. Я использую 'BehaviourSubject' для установки начальных значений, как только я получаю ответ, они заменяются новым контентом, я действительно не понимаю, что это такое и как он это делает, но это означает все мои вызовы' (radioShow $ | async) .name' и т. д. делают только один запрос и не нуждаются в '' 'like' (radioShow $ | async).? name'. – Sarcoma

Смежные вопросы