我有两个事件流:
let mouseDowns = Rx.Observable.fromEvent(document.body, "mousedown");
let mouseUps = Rx.Observable.fromEvent(document.body, "mouseup");
我想订阅mouseDown之前的所有mouseUps。
通常我会记得这样的状态:
let isDown = false;
mouseDowns.subscribe(() => down = true);
mouseUps.filter(() => isDown).subscribe(() => console.log("CAPTURED");
这感觉相当不“反应”......做同样事情的优雅方式是什么?
答案 0 :(得分:1)
我认为你正在寻找skipUntil
http://jsbin.com/tawide/edit?js,console,output
const mouseDowns = Rx.Observable.fromEvent(document.body, "mousedown");
const mouseUps = Rx.Observable.fromEvent(document.body, "mouseup");
mouseUps
.skipUntil(mouseDowns)
.subscribe(x => console.log("CAPTURED"))
(据我所知,鼠标何时不能通过鼠标向下移动?)
以上是您的代码的答案。如果你只想在一次事件发生后想要一个事件,我认为你需要一个有点难看的扫描。
// dn: ---d-------d-d----d-|
// up: u----u--u-------u---|
// : -----e----------e---|
const mouseUp = document.querySelector('.mouseUp');
const mouseDown = document.querySelector('.mouseDown');
const mouseUp$ = Rx.Observable.fromEvent(mouseUp, 'click')
.map(() => false);
const mouseDown$ = Rx.Observable.fromEvent(mouseDown, 'click')
.map(() => true);
Rx.Observable.merge(mouseUp$, mouseDown$)
.scan((acc, cur) => {
if (!cur && acc.downEvent) return ({ event: true, downEvent: false})
if (cur) return ({ event: false, downEvent: true})
return ({ event: false, downEvent: acc.downEvent})
}, {event: false, downEvent: false})
.filter(x => x.event === true)
.subscribe(
x => console.log('event!'),
(e) => console.log("error",e),
() => console.log('complete')
);
答案 1 :(得分:1)
这取决于您是否要在下一次鼠标按下之前停止听鼠标。我的意思是,如果你的目标是有一个可观察的信息,告诉你鼠标是否已关闭,你可以这样做:
const isMouseDown = Rx.Observable
.merge(
mouseDowns.map(() => true),
mouseUps.map(() => false))
.startWith(false);
isMouseDown.subscribe(state => console.log("is mouse down? " + state));
如果您想在向下/向上序列后触发,那么您可以执行以下操作:
const myClicks = mouseDowns.switchLatest(() => mouseUps);
myClicks.subscribe(() => console.log("down/up triggered"));
答案 2 :(得分:0)
好吧,我想我只是自己想出来了......
mouseDowns.map(() => mouseUps.first()).concatAll().subscribe(e => console.log(e));