使用RxJS重播具有时间戳的一系列事件

时间:2017-12-26 01:26:30

标签: rxjs rxjs5

如果我有一个包含utc时间戳和事件数据的事件数组,如下所示: [{utcts:,data:,...];

如何使用RxJS“重放”这些事件,并使用数组中每个项目之间的正确时间差异?假设数组按utcts字段排序,因此第一项具有最低值。

这是一组非常基本的数据:

myLine.StrokeThickness = 1;
myLine.Y1 = 10;
myLine.Y2 = 10;
myLine.X1 = 0;
myLine.X2 = 50;

假设utts只是从重播从0秒开始的事件开始的秒数。

3 个答案:

答案 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>

参考delayWhentimestamp

这也有效,可以说更简单,不确定哪个最好。

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)
  ))
)