Jerald
Jerald

Reputation: 4048

How to emit event not earlier than in specified timeout in RXJS?

I want to emit event after visual effects passed off. Visual effects last 5 seconds. This code works but I think there is a better solution:

Observable.combineLatest(observable1, Observable.of('hold').delay(5000)).subscribe(() => {
    alert('ok');
});

This event should be fired when observable1 is fired but not earlier than 5 seconds. (If observable1 fired after 6 seconds then this event should be fired after 6 seconds. If observable1 fired after 3 seconds then this event should be fired after 5 seconds)

Upvotes: 2

Views: 438

Answers (5)

Jerald
Jerald

Reputation: 4048

observable1.combineLatest(Observable.timer(5000))
    subscribe(([result]) => {
        alert('ok');
    });

Upvotes: 0

mperle
mperle

Reputation: 3612

Rx.js debounceTime operator emits the most recent value from the source observable only after the specified time is elapsed.

Observable1.debounceTime(5000).subscribe(() => { alert('ok') } );

Upvotes: 0

Enigmativity
Enigmativity

Reputation: 117027

My apologies for not being an RxJS coder - I code in C#. Here's how to do this in C#:

IObservable<string> query =
    Observable
        .Merge(
            observable1.Take(1).Select(x => "hold"),
            Observable.Timer(TimeSpan.FromSeconds(6.0)).Select(x => "hold"))
        .Skip(1);

Now, I can test this like this:

var observable1 = new Subject<long>();

IObservable<string> query =
    Observable
        .Merge(
            observable1.Take(1).Select(x => "hold"),
            Observable.Timer(TimeSpan.FromSeconds(6.0)).Select(x => "hold"))
        .Skip(1);

Console.WriteLine(DateTime.Now);
query.Subscribe(x => Console.WriteLine(DateTime.Now));

Thread.Sleep(1000); // 1 second
observable1.OnNext(42);

That produces:

2017/06/30 17:04:57
2017/06/30 17:05:03

Change the test code to:

Thread.Sleep(6000); // 6 seconds
observable1.OnNext(42);

And you get:

2017/06/30 17:08:49
2017/06/30 17:08:55

And finally change the test code to:

Thread.Sleep(10000); // 10 seconds
observable1.OnNext(42);

And you get:

2017/06/30 17:09:27
2017/06/30 17:09:37

Let me know if that's what you want.

Could someone please edit my answer to change my code to RxJS?

Upvotes: 2

martin
martin

Reputation: 96891

What you describe looks like you need withLatestFrom which emits only when it's source emits:

Observable
  .of('hold')
  .delay(5000)
  .withLatestFrom(observable1, (...values) => values[1])
  .subscribe(console.log);

Only the delayed 'hold' string controls when this operator emits the latest value from Observable1. The operator doesn't emit anything until both its source and Observable1 emit so even if Observable1 emits after eg. 6s you'll receive the first item after 6s. When it's the other way around and Observable1 emits earlier it'll wait for the 'hold' string.

If you're not interested in the value from Observable1 you can ignore the projection function and use just:

...
.withLatestFrom(observable1)
...

Upvotes: 2

Tamas Hegedus
Tamas Hegedus

Reputation: 29906

How about observableInstance.delay?

observable1.delay(5000).subscribe(() => {
    alert('ok');
});

Upvotes: 1

Related Questions