如果我有一个包含utc时间戳和事件数据的事件数组,如下所示: [{utcts:,data:,...];
如何使用RxJS“重放”这些事件,并使用数组中每个项目之间的正确时间差异?假设数组按utcts字段排序,因此第一项具有最低值。
这是一组非常基本的数据:
myLine.StrokeThickness = 1;
myLine.Y1 = 10;
myLine.Y2 = 10;
myLine.X1 = 0;
myLine.X2 = 50;
假设utts只是从重播从0秒开始的事件开始的秒数。
答案 0 :(得分:1)
使用delayWhen
为您提供定时重播。
由于给定的是相对(非绝对)时间,因此不需要刷新数据对象内的时间戳。
我在控制台日志中添加了一个时间戳,以便我们可以看到已用的输出时间。
请注意,额外的几毫秒是rxjs处理时间的典型值。
console.clear()
const testdata = [
{utcts: 1, data: 'a'},
{utcts: 4, data: 'b'},
{utcts: 6, data: 'c'},
{utcts: 10, data: 'd'}
];
const replayData = (data) => Rx.Observable.from(data)
.delayWhen(event => Rx.Observable.of(event).delay(event.utcts * 1000))
// Show replay items with output time (in milliseconds)
const start = new Date()
replayData(testdata)
.timestamp()
.subscribe(x => console.log(x.value, 'at', x.timestamp - start, 'ms'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>
这也有效,可以说更简单,不确定哪个最好。
mergeMap()
使内部observable变平,这是应用延迟所必需的。
const replayData = (data) => Rx.Observable.from(data)
.mergeMap(event => Rx.Observable.of(event).delay(event.utcts * 1000))
答案 1 :(得分:0)
粗伪(直接来自我的脑袋,没有运行验证)可能类似于
Observable.scan((acc, value) => ({
delay: delay === NaN ? value.utcts - delay,
value
}), { delay: NaN, value: null })
.mergeMap(({delay, value}) => Observable.from(value).delay(delay))
scan
运算符与reduce
类似,但会发出中间值。在时间之间使用该计算差异来获得这些值的延迟,然后在给定的延迟时间内发出值。还有其他几种方法可以以相同的方式工作。
答案 2 :(得分:0)
这应该在https://rxviz.com中起作用(在此处复制粘贴):
const { delay, mergeMap } = RxOperators;
const { from, Observable, of } = Rx;
const testdata = [
{utcts: 0.2, data: 'a'},
{utcts: 2.0, data: 'b'},
{utcts: 2.8, data: 'c'},
{utcts: 4.0, data: 'd'}
];
from(testdata).pipe(
mergeMap(event => of(event).pipe(
delay(event.utcts * 1000)
))
)