Rxjs Switchmap太早取消订阅

时间:2020-09-26 21:18:14

标签: javascript reactjs events rxjs

我有这段代码来跟踪位置变量,上游事件是键盘侦听器。我想发出“开始”位置,以便在进行任何真正的按键操作之前先在​​屏幕上绘制播放器,所以我建立了这个可观察的物体,它从无声开始,以发出没有任何移动的开始位置:

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。

有人可以帮忙解释此行为吗?是否有任何解决方法?我不希望不必使用一些缓冲的可观察对象,它的窗口足够大,可以将事件放到下游,因为从长远来看这似乎是不可维护的,而且我也不必一开始就这样做。

1 个答案:

答案 0 :(得分:1)

在评论中继续讨论:我很确定这是怎么回事:

  • 第一个事件传递到switchMap,并订阅了$animationEvent
  • $animationEvent发出任何值之前,第二个事件传递给switchMap,结果$animationEvent在有机会触发任何值之前被取消订阅。
  • 第二个事件映射到EMPTY,所以最后在switchMap之后什么也没有发出。

如果我做对了,而您想要做的就是添加开始事件,那么在流水线的末尾添加startWith是可行的-它只会发出这两个开始事件,前两个值。如果您看到它多次发出两个值,则意味着subscribe被多次调用。容易导致此错误的一个错误是订阅了React.useEffect回调,而忘记添加[]作为第二个参数。