简体   繁体   中英

RxJS cancel overlapping events and delay

How to delay 300ms and take only last event from mouseLeave event stream Observable in RxJS? I wanted to take latest event only and delay it to 300 milli seconds then fire a method.

class MouseOverComponent extends React.Component {
  state = {menuIsOpen: false}

  componentDidMount() {
    this.mouseLeave$ = Rx.Observable.fromEvent(this.mouseDiv, "mouseleave")
      .delay(300)
      .throttleTime(300)
      .subscribe(() => /* here I want to hide the div */);
  }

  componentWillUnmount() {
     this.mouseLeave$.unsubscribe();
  }

  menuToggle = e => {
    e && e.preventDefault()
    let {menuIsOpen} = this.state
    menuIsOpen = !menuIsOpen
    this.setState({menuIsOpen, forceState: true})
  }

  render() {
    // const menuStateClass = ... resolving className with state
    return (
      <div ref={(ref) => this.mouseDiv = ref}>
          Move the mouse and look at the console...
      </div>
    );
  }
}

but its not working its firing previous events also. Its hiding and showing uncontrollable while i do fast mouse leave.

I want mouseDiv when mouse leaves from the div and wait for 300ms then hide.

I think by "take latest event only" you mean you want to get the last value from fromEvent(this.mouseDiv, "mouseleave") when you call this.mouseLeave$.unsubscribe(); .

By calling .unsubscribe() you dispose the chain which is not what you want in this case. Instead you can use takeUntil and takeLast(1) operators like the following to complete the chain that triggers takeLast(1) that passes the last value it received:

componentDidMount() {
  this.mouseLeave$ = Rx.Observable.fromEvent(this.mouseDiv, "mouseleave")
    .takeUntil(this.unsub$)
    .takeLast(1)
    .delay(300)
    .subscribe(() => /* here I want to hide the div */);
}

componentWillUnmount() {
   this.unsub$.next();
}

Add a first() and repeat() will reset your stream from clean state and it probably can solve your issue.

 Rx.Observable.fromEvent(block, "mouseleave")
      .delay(300)
      .throttleTime(300)
      .first()
      .repeat()
      .subscribe(console.log);

fiddle: http://jsfiddle.net/cy0nbs3x/1384/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM