如何创建一个跳过两个事件之间的发射的可观察对象
How to create an observable that skips emissions between 2 events
上下文是一架音乐钢琴。我有兴趣捕捉 key-up 发生的事件 当延音踏板未被按下时 .
我有这些流:
pedalDown$
pedalUp$
keyUp$
我如何将它们组合到一个可观察的 unsustainedUp$
中,仅当踏板未踩下时才发出 keyUp$
事件?
我认为这可行,但即使 keyUp$
在 pedalDown$
之后和 pedalUp$
之前,unsustainedUp$
也会触发。
unsustainedUp$ = keyUp$.pipe(
skipUntil(pedalUp$),
takeUntil(pedalDown$),
repeat()
)
// once at setup, fire into pedal-up to get this into the correct, normal piano initial state
pedalUp$.next()
我想你可以这样做。根据 pedalUp$
功能,您可能需要 startWith()
。
顺便说一句,pedalDown$
和其他 Subjects
、BehaviorSubjects
或 ReplaySubjects
?:
pedalUp$.pipe(
switchMap(() => keyUp$.pipe(
takeUntil(pedalDown$),
)),
现场演示:https://stackblitz.com/edit/rxjs-v2wkhq?devtoolsheight=60
我也尝试了您的解决方案,因为在我看来它应该也能正常工作,而且确实如此:
https://stackblitz.com/edit/rxjs-ngorgw?devtoolsheight=60
因此请确保源 Observables 何时发出,因为这可能是问题所在。
您的流设置使这有点困难。一种方法是对踏板当前是否在其自己的流中向上进行编码,当踏板向上时发出 true,当踏板向下时发出 false。这里我默认了true
(踏板启动)。
然后我们可以将两者结合起来,在踩下踏板时过滤掉所有值,然后在适当的时候发出 keyUp$
值。
像这样:
const isPedalUp$ = merge(
pedalUp$.pipe(mapTo(true)),
pedalDown$.pipe(mapTo(false))
).pipe(
startWith(true)
);
unsustainedUp$ = keyUp$.pipe(
withLatestFrom(isPedalUp$),
filter(([_,isUp]) => isUp),
map(([kepUp,_]) => kepUp)
);
另一种方法是切换进出 keyUp$
。如果还没有,您需要多播 keyUp$
。
unsustainedUp$ = merge(
pedalUp$.pipe(mapTo(true)),
pedalDown$.pipe(mapTo(false))
).pipe(
startWith(true),
switchMap(isUp => isUp ?
keyUp$,
EMPTY
)
);
上下文是一架音乐钢琴。我有兴趣捕捉 key-up 发生的事件 当延音踏板未被按下时 .
我有这些流:
pedalDown$
pedalUp$
keyUp$
我如何将它们组合到一个可观察的 unsustainedUp$
中,仅当踏板未踩下时才发出 keyUp$
事件?
我认为这可行,但即使 keyUp$
在 pedalDown$
之后和 pedalUp$
之前,unsustainedUp$
也会触发。
unsustainedUp$ = keyUp$.pipe(
skipUntil(pedalUp$),
takeUntil(pedalDown$),
repeat()
)
// once at setup, fire into pedal-up to get this into the correct, normal piano initial state
pedalUp$.next()
我想你可以这样做。根据 pedalUp$
功能,您可能需要 startWith()
。
顺便说一句,pedalDown$
和其他 Subjects
、BehaviorSubjects
或 ReplaySubjects
?:
pedalUp$.pipe(
switchMap(() => keyUp$.pipe(
takeUntil(pedalDown$),
)),
现场演示:https://stackblitz.com/edit/rxjs-v2wkhq?devtoolsheight=60
我也尝试了您的解决方案,因为在我看来它应该也能正常工作,而且确实如此:
https://stackblitz.com/edit/rxjs-ngorgw?devtoolsheight=60
因此请确保源 Observables 何时发出,因为这可能是问题所在。
您的流设置使这有点困难。一种方法是对踏板当前是否在其自己的流中向上进行编码,当踏板向上时发出 true,当踏板向下时发出 false。这里我默认了true
(踏板启动)。
然后我们可以将两者结合起来,在踩下踏板时过滤掉所有值,然后在适当的时候发出 keyUp$
值。
像这样:
const isPedalUp$ = merge(
pedalUp$.pipe(mapTo(true)),
pedalDown$.pipe(mapTo(false))
).pipe(
startWith(true)
);
unsustainedUp$ = keyUp$.pipe(
withLatestFrom(isPedalUp$),
filter(([_,isUp]) => isUp),
map(([kepUp,_]) => kepUp)
);
另一种方法是切换进出 keyUp$
。如果还没有,您需要多播 keyUp$
。
unsustainedUp$ = merge(
pedalUp$.pipe(mapTo(true)),
pedalDown$.pipe(mapTo(false))
).pipe(
startWith(true),
switchMap(isUp => isUp ?
keyUp$,
EMPTY
)
);