尝试使用RxJS v5构建计划,其中某些事件可以触发计划重新加载。目前使用3个来源 - 安排$,event $和userNotification $(以下示例)。
我已经尝试了许多不同的策略,并且当reloadSchedule事件时间到来时,我一直变得像递归重新加载这样的怪异。有没有办法让下游数据(事件$)干净地触发上游(计划$)重新加载,而没有任何行动/通知从先前的计划项目中延续下来?
schedule$ = new Rx.BehaviorSubject(
{schedule:[
{start:'1pm', end:'2pm', action:'sayhi'},
{start:'2pm', end:'3pm', action:'sayhi'},
{start:'3pm', end:'3pm', action:'reloadSchedule'},
{start:'3:01pm', end:'4pm', action:'sayhi'},
]}
);
function loadSchedule(){
somethingAsync.then((moreData)=>schedule$.next(moreData));
}
event$ = schedule$.flatMap((data)=>{
return Rx.Observable
.from(data.schedule)
.flatMap((event)=>{
return Rx.Observable.timer(event.start)
.flatMap(()=>{
// do actions here once previous actions/notifications finish
if(event.action === 'reloadSchedule'){
loadSchedule()
}
return Rx.Observable.of(someUserMessage);
})
})
})
userNotification$ = Rx.Observable.timer(1000).withLatestFrom(event$)
.flatMap((someUserMessage)={
// fade message after 5 seconds
});
userNotification.subscribe(()=>{});
答案 0 :(得分:0)
结束找出解决方案。可能有更简洁的方法,但它有效。
基本思想是拥有一个控制动作的计时器。将事件时间与该计时器进行比较,以获得正确的当前事件。在需要重新加载时取消订阅。
粗略的例子。
// start and end are ISO strings - showing 1pm etc.
let schedule$ = new Rx.BehaviorSubject([
{start:'1pm', end:'2pm', action:'sayhi'},
{start:'2pm', end:'3pm', action:'sayhi'},
{start:'3pm', end:'3pm', action:'reloadSchedule'},
{start:'3:01pm', end:'4pm', action:'sayhi'},
]);
schedule$.subscribe((sched)=>{
new Scheduler(sched)
});
function loadSchedule(){
somethingAsync.then((moreData)=>schedule$.next(moreData));
}
class Scheduler{
constructor(schedule){
let notificationsCleared = true;
let sliced;
let event$ = Rx.Observable
.timer(1000)
.filter(()=>notificationsCleared)
.map(()=>{
let now = (new Date()).toISOString();
sliced || (sliced = schedule.slice(0));
while (now > sliced[0].end){
sliced.shift();
}
return sliced[0];
}).share();
let cleanup$ = event$.filter((evt)=>evt.action === 'reloadSchedule')
let userNotification$ = event$.map(()=>{
notificationsCleared = false;
someAsyncNotification()
.then(()=>notificationsCleared = true)
});
let userSub = userNotification.subscribe(()=>{});
let cleanupSub = cleanup$.subscribe(()=>{
loadSchedule();
userSub.unsubscribe();
cleanupSub.unsubscribe();
});
}
};