Rxjs:如果之前发生了另一个事件,如何订阅事件?

时间:2016-11-17 13:35:05

标签: javascript rxjs

我有两个事件流:

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");

这感觉相当不“反应”......做同样事情的优雅方式是什么?

3 个答案:

答案 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));