如果有可观察到的相同发射,则取消延迟

时间:2019-04-25 14:17:28

标签: javascript rxjs observable

const observable = new rxjs.BehaviorSubject(0);

observable.subscribe(v => console.log(v));

rxjs
  .of(1)
  .pipe(rxjs.operators.delay(500))
  .subscribe(v => observable.next(v));
  
observable.next(2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>

如您所见,上面的观察对象按顺序发出3个值:0、2、1。

发出值“ 2”时,可以取消(或忽略)值“ 1”吗? (不关闭订阅)

3 个答案:

答案 0 :(得分:2)

您要查找的运算符是debounceTime

  

debounceTime

     

仅在经过特定时间段后才发出源Observable的值,而不会发出其他源信号。

source

rxjs.interval(100)
  .pipe(
    rxjs.operators.take(10),
    rxjs.operators.debounceTime(500)
  )
  .subscribe((v)=>{
    console.log(v);
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>

答案 1 :(得分:1)

因此对于鼠标进入和离开,您正在寻找debounceTime例如:

const observable = new BehaviorSubject(0);
observable
  .pipe(debounceTime(500))
 .subscribe(console.log);

observable.next(1),
observable.next(2);
setTimeout(() => observable.next(3) , 1000)

在此示例中,将打印2,而第二个打印3。 在每个发出值之后,可观察的等待500 ms,如果没有新值,它将在订阅中打印,否则它将取消最后一个值并再次开始此过程,希望这可以解决您的问题

答案 2 :(得分:1)

似乎您需要从源头上switchMap并在其中应用delay

switchMap(value =>
 of(value).pipe(delay(50))
)

插图和 playground for switchMap with a delay

delay with a switchMap

还有一个摘要:

const {Subject, of} = rxjs;
const {switchMap, delay} = rxjs.operators;

const subject = new Subject(0);

subject
  .pipe(
     switchMap(value =>
       // switchMap to a delayed value
       of(value).pipe(delay(500))
     )
  )
  .subscribe(v => console.log(v));

// immediately emit 0
subject.next(0);

// emit 1 in 1 sec
setTimeout(()=>{
  subject.next(1);
}, 1000)

// emit 2 in 1.2 sec
setTimeout(()=>{
  subject.next(2);
}, 1200)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>

这里有一个鼠标悬停示例

const {fromEvent, merge, of, EMPTY} = rxjs;
const {switchMap, delay, mapTo} = rxjs.operators;

const button = document.getElementById('pane');
const mouseOver$ = fromEvent(button, 'mouseover').pipe(
  mapTo(true)
);

const mouseOut$ = fromEvent(button, 'mouseout').pipe(
  mapTo(false)
);

merge(mouseOver$, mouseOut$)
  .pipe(
     switchMap(value => {
       if (!value) { return EMPTY; }
       return of('mouse is over').pipe(delay(500))
     })
  )
  .subscribe(v => console.log(v));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>

<style>
#pane{
  margin: 1rem;
  display: inline-block;
  width: 5rem;
  height: 5rem;
  background: rebeccapurple;
}</style>

<div id="pane"><div>

希望这会有所帮助