אנגולר - לבצע בקשת API בזמן נתון כדי לעדכן את תוכנית הרדיו הנוכחית Angular2 RxJS
אני עובד על לוח זמנים לתחנת רדיו קהילתית ותהיתי כיצד אני יכול לעדכן את התוכנית הנוכחית שמשודרת.
הגעתי עד כדי סקר של השרת פעם בדקה (לא בטוח שזה הדרך הנכונה, אבל זה יעבוד בלחץ), אבל בהתחשב בכך שיש לי את זמן הסיום מה-API תהיתי אם אני יכול להגדיר אותו להתעדכן לאחר שזמן הסיום יעבור ואז להגדיר Observer חדש עם זמן הסיום הבא.
האם למישהו יש רעיון איך אני יכול להשיג את זה, או שיש דרך טובה יותר לגשת לעדכון התוכנית הנוכחית?
מה שאני באמת מתקשה בו הוא להבין את המושגים Observables ו-Subscribers. איך אני יכול לקבל גישה ל-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-3 בין כל קריאה כדי לדמות את המקום שבו בדרך כלל היית מחשב את העיכוב.
