Reputation: 415
I have a computationally heavy section of code which performs filtering of a data-set by DOM-manipulations. I made it async in order to ensure acceptable performace for large number of fiter items:
.on('input', function {
setTimeout(function(){
// heavy computation
}, 0)
})
The problem is that this section probably run on every user input change but only the result of the last one is of interest. So, my question is if there is a way to cancel the previous "threads" executing the heavy computation section and only execute the latest?
The best idea I have thus far is to use some sort of semaphore (possibly $.Deferred) and try to reduce the critical section.
Upvotes: 3
Views: 78
Reputation: 191976
If you only need the final result, use debounced
event handler. This is a sample debounce implementation, but there are other on the web.
Wrapping your event handler with debounce
will prevent the event handler from firing, as long as it's called repeatedly. The handler will fire, only if the handler is called, and then it's idle for a set amount of time.
.on('input', debounce(function {
// heavy computation
}, 500)) // wait 500ms before firing the handler
In the example type continuously and stop, you'll see that the console will log the word called only once:
var debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this,
args = arguments;
var later = function() {
timeout = null;
if ( !immediate ) {
func.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait || 200);
if ( callNow ) {
func.apply(context, args);
}
};
};
$('#input').on('input', debounce(function() {
console.log('called');
}));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="input">
Upvotes: 2