There are multiple ways to do it.
One way would be to create a RxJS Subject
and route the function calls to emit a notification from it. And in the subscription to this observable you could use RxJS throttleTime
operator to ignore the subsequent emissions for a specified amount of time.
Try the following
Controller
import { Subject } from 'rxjs';
import { throttleTime, takeUntil } from 'rxjs/operators';
export class AppComponent implements OnInit, OnDestroy {
completed$ = new Subject<any>();
trigger$ = new Subject<any>();
constructor() { }
functionWithTimeLimit() {
console.log('called functionWithTimeLimit');
}
ngOnInit() {
this.trigger$.pipe(
throttleTime(2000), // <-- ignore notifications for 2s after an emission
takeUntil(this.completed$) // <-- use to close the subscription
).subscribe(this.functionWithTimeLimit.bind(this));
}
ngOnDestroy() {
this.completed$.next(); // <-- close impending subscriptions
}
}
Template
<button (mouseup)="trigger$.next()">Trigger function</button>
Working example: Stackblitz
In the above example, say originally the button press was supposed to trigger the function directly. But now we emit the observable when the button is pressed and trigger the function in it's subscription.
Update: Difference between throttleTime
and debounceTime
throttleTime
will suspend subsequent notifications for a fixed amount of time after a single notification.
var { fromEvent } = rxjs;
var { throttleTime, map } = rxjs.operators;
var inputBox = document.getElementById('search');
var displayBox = document.getElementById('display');
fromEvent(inputBox, 'keyup').pipe(
map(event => event.currentTarget.value),
throttleTime(2000),
).subscribe(value => displayBox.innerHTML = value);
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>
Keep on typing. It will render the value continuously every 2 sec.<br><br>
<input type="text" id="search" />
<p id="display"></p>
debounceTime
will suspend subsequent notifications for a fixed amount of time after every notification.
var { fromEvent } = rxjs;
var { debounceTime, map } = rxjs.operators;
var inputBox = document.getElementById('search');
var displayBox = document.getElementById('display');
fromEvent(inputBox, 'keyup').pipe(
map(event => event.currentTarget.value),
debounceTime(2000),
).subscribe(value => displayBox.innerHTML = value);
<script src="https://unpkg.com/rxjs@6.4.0/bundles/rxjs.umd.min.js"></script>
Keep on typing. It'll render only after 2 seconds after the typing stops.<br><br>
<input type="text" id="search" />
<p id="display"></p>