RxJs:基于计数的可变样本大小

时间:2018-05-24 21:04:21

标签: javascript rxjs

我对RxJS很陌生,我试图围绕一些概念,但感觉我仍然缺少正确的心态。

我一直在修补感觉的东西,就像它应该很简单,但到目前为止还没有成功。我正在听DOM并包装" keydown"和#34; keyup" Observables中的事件

const keyDown$ = Observable.fromEvent(window, 'keydown');
const keyUp$ = Observable.fromEvent(window, 'keyUp');

另一方面,我有一个听众

keyDown$
    .filter(/logic to get the right arrow keycode/)
    .subscribe(downArrow => moveElementToTheRight())

这里的问题是,如果按住键,你每隔x毫秒就会获得一个值,因此元素移动的速度非常快。这非常简单,可以纠正

keyDown$
    .filter(/logic to get the right arrow keycode/)
    .sample.pipe(interval(200))
    .subscribe(downArrow => moveElementToTheRight())

我想要实现的目标有点不同,因为我希望样本大小随着用户持续按住键而改变,在某种 ease-in < / em>时尚。例如,如果用户持有该键三秒钟,则:

  • 0到1秒:每半秒发光一次
  • 1到2秒:发射200毫秒
  • 超过2秒:发出每个值

到目前为止,我试图想出最好的方法但没有成功。我的第一个想法是使用 map 来获取keydown的计数

keyDown$
    .filter(/logic to get the right arrow keycode/)
    .map((value, index) => 
        if index < 10 return value every 500ms
        if index between 10 and 20 return value every 200ms
        /etc/

这个问题是索引永远不会返回0.然后我试图找到一种方法来根据Subjects和keyUp事件重新初始化索引,但它不知何故感觉错误并让我我觉得我没有朝着正确的方向前进。

我已经添加了一个快速的JSBin,我已经在那里使用扫描返回命令和keydown的持续时间。我想我之后可以使用switchMap语句,但是仍然有人觉得......错了吗?

http://jsbin.com/jahoqocuxa/edit?js,console,output

我非常感谢一些知识渊博的人的一些意见。

1 个答案:

答案 0 :(得分:1)

我认为您采用的scan方法很好,可能有点必要。

我认为您可以使用window运算符很好地模拟您想要的行为。必须将流切入窗口,分隔符为keyUp$发射。流被转换为更高阶的Observable(Observable of Observables)。因此,在map运算符中,您可以处理各个窗口段。在下面的示例中,前3个排放映射到A,其余排放到B。最后,使用mergeAll,更高阶的Observable被展平为A&amp;的普通流。 B排放量。

const keyDown$ = Rx.Observable.fromEvent(window, 'keydown');
const keyUp$ = Rx.Observable.fromEvent(window, 'keyup');

keyDown$
  .window(keyUp$)
  .map(win => win.map((_, idx) => idx > 2 ? 'B' : 'A'))
  .mergeAll();
  .subscribe(console.log);

按键2秒,然后释放并再次按下时控制台输出应如下所示:

"A"
"A"
"A"
"B"
"B"
"B"
"A"
"A"
"A"
"B"
"B"