Отмените задержку, если испускаются такие же наблюдаемые - PullRequest
0 голосов
/ 25 апреля 2019

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.

Можно ли отменить(или игнорировать) значение «1», когда выбрасывается значение «2»?(Без закрытия подписки)

Ответы [ 3 ]

2 голосов
/ 25 апреля 2019

Оператор, который вы ищете: debounceTime:

debounceTime

Издает значение из источника Наблюдаемый только после того, как определенный промежуток времени прошел без другого источникаэмиссия.

источник

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 голос
/ 26 апреля 2019

Похоже, вам нужно switchMap из вашего источника и применить delay внутри него.

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

Иллюстрация и площадка для SwitchMap с задержкой :

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>

Надеюсь, это поможет

1 голос
/ 25 апреля 2019

Таким образом, для ввода и выхода мыши вы ищете 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 мс, и если новое значение не будет напечатано в подписке, иначе оно отменит последнее и снова запустит этот процесс, надеюсь, это решит вашу проблему

...