我对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>时尚。例如,如果用户持有该键三秒钟,则:
到目前为止,我试图想出最好的方法但没有成功。我的第一个想法是使用 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
我非常感谢一些知识渊博的人的一些意见。
答案 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"