我有这段代码来跟踪位置变量,上游事件是键盘侦听器。我想发出“开始”位置,以便在进行任何真正的按键操作之前先在屏幕上绘制播放器,所以我建立了这个可观察的物体,它从无声开始,以发出没有任何移动的开始位置:
const Z=`how can i write variable ${Y}`;
问题似乎是switchMap运算符在传递第二个开始事件后立即取消了$ animationEvent,这似乎是在第一个事件可以发送给订阅者之前发生的。当我在switchMap之前点击事件时,这是输出:
$keyboardEvent.pipe(
startWith(
{
key: Key.Noop,
keys: [Key.Noop],
keyStroke: KeyStroke.Down,
},
{ key: Key.Noop, keys: [], keyStroke: KeyStroke.Up }
),
tap(({ keys }) => (keysRef.current = keys)),
switchMap(() => (keysRef.current.length > 0 ? $animationEvent : EMPTY)),
map(() => {
if (keysRef.current.length > 0) {
playerPosition.current = updatePlayerPosition(keysRef.current);
playerRotation.current = updatePlayerRotation(keysRef.current);
}
playerMovementState.current =
keysRef.current.length > 0 ? "active" : "idle";
return {
position: playerPosition.current,
rotation: playerRotation.current,
state: playerMovementState.current,
};
})
)
当我在switchMap之后点击时,没有任何结果,即使我知道在传递第一个事件之后会返回$ animationEvent。
有人可以帮忙解释此行为吗?是否有任何解决方法?我不希望不必使用一些缓冲的可观察对象,它的窗口足够大,可以将事件放到下游,因为从长远来看这似乎是不可维护的,而且我也不必一开始就这样做。
答案 0 :(得分:1)
在评论中继续讨论:我很确定这是怎么回事:
switchMap
,并订阅了$animationEvent
。$animationEvent
发出任何值之前,第二个事件传递给switchMap
,结果$animationEvent
在有机会触发任何值之前被取消订阅。EMPTY
,所以最后在switchMap
之后什么也没有发出。如果我做对了,而您想要做的就是添加开始事件,那么在流水线的末尾添加startWith
是可行的-它只会发出这两个开始事件,前两个值。如果您看到它多次发出两个值,则意味着subscribe
被多次调用。容易导致此错误的一个错误是订阅了React.useEffect
回调,而忘记添加[]
作为第二个参数。