我正在尝试使用 Rxjs 和 mousedown、mouseup 和 mousemove 事件创建自己的单击、按住和拖动事件。我的尝试使用了许多以 mousedown 事件开头的流,每个流都有一个 takeUntil 来监听来自其他流的发射。基本上,一旦其中一个流“声明”了该操作(即通过了所有要求并发出了一个值),其他 observables 应该在没有排放的情况下完成。
我查看了其他答案,并认为它可能与运行异步的计时器有关,但它发生在不依赖计时器的流之间,例如拖动和单击。我一直在使用 rxjs v6 在 codesandbox.io 中玩耍。
takeUntil 也必须坐在内部 observables 上,因为我不希望外部 observables 运行一次并完成。
代码如下所示:
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"));
预期行为:
如果用户在 mousedown 事件的 1 秒内移动鼠标,则mouse_drag$
流应该开始发射并且mouse_Click$/mouse_Hold$
的内部 observables 应该完成(感谢takeUntil(mouse_drag$)
没有发射并等待下一次发射mouse_down$
。
如果鼠标按钮在不移动的情况下保持按下状态超过 1秒,则mouse_Hold$
应该发出并且mouse_drag$/mouse_click$
的内部 observable 应该完成(感谢takeUntil(mouse_Hold$)
没有发出并等待下一次发射mouse_down$
。
实际行为:当前mouse_Drag$
会发出,mouse_Hold$
一秒后mouse_Click$
会发出,松开按钮时会发出。
我的问题是为什么发射mouse_Drag$
流不会导致mouse_Hold$
andmouse_Click$
的内部 observable 完成而不发射?