我有一些预先定义的事件设置为在特定时间发生。 我有一个计时器,像这样:
const timer = Rx.Observable.interval(100).timeInterval()
.map(x => x.interval)
.scan((ms, total) => total + ms, 0)
计时器发出接近100,200,300,400,500的东西(虽然实际上它更像101,200,302,401,500 ......这完全没问题) 我也有一些我想在某些时候做的事情。例如,让我们说我想在以下时间做一些事情:
const stuff = Rx.Observable.from([1000, 2000, 2250, 3000, 5000]);
我想要的是结合"东西"和"计时器"以这样的方式,结果流每次在" stuff"中定义一次值。那个时候(或者稍晚一点)。在这种情况下,这将是t = 1000毫秒,2000毫秒,2250毫秒,3000毫秒和5000毫秒。注意:由于间隔大小,2250人应该在2300左右发射。没关系。他们不能提前或不止一次。
我有一个解决方案,但它并不是很好。它重新开始"东西"每一步(在这种情况下每一个100毫秒)并过滤它并采取1.我希望,一旦事件从"东西"发出,它就会消失,所以后续的过滤器就不会#39; t有这些值。
在真正的应用程序中,会有东西和东西2,也许东西3 ...(但我会称之为别的东西!)
提前致谢!我希望这很清楚。
答案 0 :(得分:5)
如果我已经理解了你正确的事情,这应该可以通过一个简单的预测来实现:
const times$ = stuff.flatMap(x => Rx.Observable.timer(x));
以下是一个工作示例:https://jsbin.com/negiyizibu/edit?html,js,console,output
修改
对于第二个要求,请尝试以下方法:
const times$ = Rx.Observable
.from([{"val":"jeff", "t": 1000}, {"val":"fred", "t": 2500}])
.flatMap(x => Rx.Observable.timer(x.t).map(y => x.val));
答案 1 :(得分:0)
这是我根据 Matt 的解决方案编写的打字稿函数。
import {from, timer} from 'rxjs';
import {flatMap, map} from 'rxjs/operators';
export interface ActionQueueEntry {
action: string;
payload?: any;
delay: number;
}
export function actionQueue(entries: ActionQueueEntry[]) {
return from(entries).pipe(flatMap((x: any) => {
return timer(x.delay).pipe(map(y => x));
}));
}
const q = actionQueue([
{action: 'say: hi', delay: 500},
{action: 'ask: how you are', delay: 2500},
{action: 'say: im fine', delay: 5000},
]);
q.subscribe(console.log);