admin管理员组文章数量:1303353
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=".5.1/rxjs.umd.js"></script>
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./ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>
As you can see, the observable above emits 3 values in order : 0, 2, 1.
Would it be possible to cancel (or ignore) the value "1" when the value "2" is emitted ? (Without closing the subscription)
Share Improve this question asked Apr 25, 2019 at 14:17 user4676340user4676340 8- There are better ways to emit numbers one after another, rxjs timer for example. in any case, if you have an observable with subscription and want that new value that emited will cancel the last subscription and switch to a new one read about switchMap. But i'm not sure if it's possible in this code that you added above – Lagistos Commented Apr 25, 2019 at 14:26
-
@Lagistos this is a minimal reproducible example. I used numbers to be quick. In reality, the
next
s are called on mouse events. I would like to cancel the delayedmouseenter
onmouseleave
, because otherwise, the leave emits, then the enter does too. – user4676340 Commented Apr 25, 2019 at 14:28 -
Based on what condition you want to ignore the last value? You could use
ignoreElements()
beforedelay
if you never want to receive the value fromof
. Or you can also useEMPTY
as your source Observable. – martin Commented Apr 25, 2019 at 14:31 - There's no condition, I would like to cancel a delayed emition if a new emition es up. I know that you can use SwitchMap for that, but I don't know how to use it for a single observable. – user4676340 Commented Apr 25, 2019 at 14:36
-
1
use
debounceTime(500)
instead ofdelay(500)
. @trichetriche – n00dl3 Commented Apr 25, 2019 at 16:20
3 Answers
Reset to default 7Seems like you need to switchMap
from your source and apply a delay
inside of it.
switchMap(value =>
of(value).pipe(delay(50))
)
An illustration and a playground for switchMap with a delay:
And heres a snippet:
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./ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>
Heres an example with mousehover
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./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>
Hope this helps
The operator you are looking for is debounceTime
:
debounceTime
Emits a value from the source Observable only after a particular time span has passed without another source emission.
source
rxjs.interval(100)
.pipe(
rxjs.operators.take(10),
rxjs.operators.debounceTime(500)
)
.subscribe((v)=>{
console.log(v);
});
<script src="https://cdnjs.cloudflare./ajax/libs/rxjs/6.5.1/rxjs.umd.js"></script>
So for mouse enter and leave you are looking for debounceTime for example:
const observable = new BehaviorSubject(0);
observable
.pipe(debounceTime(500))
.subscribe(console.log);
observable.next(1),
observable.next(2);
setTimeout(() => observable.next(3) , 1000)
In this example that will print 2 and after one seconed 3. After each emitited value the observable wait for 500 ms and if there are no new value it will print in the subscribe else it will cancel the last one and start this proccess again, hope this will solve your problem
本文标签: javascriptCancel a delay if same observable emitsStack Overflow
版权声明:本文标题:javascript - Cancel a delay if same observable emits - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741726228a2394632.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论