Я пытаюсь создать свои собственные события щелчка, удержания и перетаскивания, используя Rxjs и события mousedown, mouseup и mousemove.Мои попытки используют несколько потоков, которые начинаются с события mousedown, каждый с takeUntil, который прослушивает выбросы из других потоков.По сути, как только один из потоков «заявил» о действии (то есть прошел все требования и выдал значение), другие наблюдаемые должны завершиться без выбросов.
Я посмотрел на другие ответы и подумал, что это может что-то иметьделать с таймером, работающим асинхронно, но это происходит между потоками, которые не используют таймер, например, перетаскиваниеЯ играл в кодахandbox.io, используя rxjs v6.
TakeUntil также должен сидеть на внутренних наблюдаемых, так как я не хочу, чтобы внешние наблюдаемые запускались один раз и выполнялись.
Код показан ниже:
const mouse_Down$ = fromEvent(document, "mousedown").pipe(
tap(event => event.preventDefault())
);
const mouse_Up$ = fromEvent(document, "mouseup").pipe(
tap(event => event.preventDefault())
);
const mouse_Move$ = fromEvent(document, "mousemove");
const mouse_drag$ = mouse_Down$
.pipe(
mergeMap(mouseDownEvent =>
mouse_Move$.pipe(takeUntil(merge(mouse_Up$, mouse_Hold$, mouse_drag$)))
)
).subscribe(event => console.log("Drag"));
const mouse_Hold$ = mouse_Down$
.pipe(
mergeMap(mouseDownEvent =>
timer(1000).pipe(takeUntil(merge(mouse_drag$, mouse_Click$)))
)
).subscribe(event => console.log("Hold"));
const mouse_Click$ = mouse_Down$
.pipe(
mergeMap(mouseDownEvent =>
mouse_Up$.pipe(takeUntil(mouse_drag$, mouse_Hold$))
)
).subscribe(event => console.log("Click"));
Ожидаемое поведение: Если пользователь перемещает мышь в течение 1 с после события mousedown, поток mouse_drag$
должен начать излучаться, а внутренняя наблюдаемая mouse_Click$/mouse_Hold$
должна завершиться (благодаря takeUntil(mouse_drag$)
безиспускание и ожидание следующей эмиссии mouse_down$
.
Если кнопка мыши остается нажатой в течение более 1 с без движения, mouse_Hold$
должен испустить и внутренняя наблюдаемая mouse_drag$/mouse_click$
должна завершиться (благодаря takeUntil(mouse_Hold$)
без излучения и ожидайте следующего mouse_down$
излучения.
Фактическое поведение: В настоящее время mouse_Drag$
будет излучать, mouse_Hold$
будет излучать через одну секунду, а mouse_Click$
будетemit, когда кнопка отпущена.
Мой вопрос: почему из-за излучающего потока mouse_Drag$
внутренняя наблюдаемая mouse_Hold$
и mouse_Click$
не завершается без излучения?