6 ms·
Underscore has a nifty function, _.debounce, which given a function f, returns a version of the function that behaves as the one in your interview question. htt
by mdkess 13y ago
Underscore has a nifty function, _.debounce, which given a function f, returns a version of the function that behaves as the one in your interview question. http://underscorejs.org/#debounce http://underscorejs.org/#debounce Even if not using libraries, it would be nice to abstract that into its own function when you inevitably want to use it again in some other control.
The code is pretty simple - very similar to what you did:
function (func, wait, immediate) {
var timeout, args, context, timestamp, result;
return function() {
context = this;
args = arguments;
timestamp = new Date();
var later = function() {
var last = (new Date()) - timestamp;
if (last < wait) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) result = func.apply(context, args);
}
};
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (callNow) result = func.apply(context, args);
return result;
};
}
- rvivek 13y agoI'm guessing underscore's throttle function would be the better way, if underscore is available.
- aroman 13y agoThis is precisely what I would have suggested I would use if I were asked such a question.
- mdkess 13y agoThrottle is different, it's a rate limiter, whereas debounce just measures delays between calls. With throttle, the server request would be made every 200ms rather than 200ms after the user stops typing. From a user experience though, throttle feels like a better way to approach this, since it would let you update the list at a measured pace, but it would be incorrect for the problem as described.
- thedz 13y agoRight, from a UX perspective, throttle makes more sense due to more constant feedback. You want the user to realize that it is a live search before they finish typing. Else, they'll just type the entire query. But obviously, in this case, the interviewer specifically outlined requirements that would make debounce the better choice than throttle.
- mercer 13y agoGood point. I've generally used debounce for live search, and throttle for window resizing, among other things. In hindsight throttle is perhaps better for live search as well.
- thedz 13y agoFor window resizing, i'd actually use debounce. Most times, a user resizes a window with a predetermined size in mind -- they want to show something behind the window, or want to make the window fill an existing space. In that case, showing live updates in the window during resizing might not be worth it.
- STRML 13y agoAs other comments have pointed out, `_.debounce` is the correct answer. Here's the bit from the docs that always reminds me when to use `_.debounce` over throttle: _.debounce: [...] Useful for implementing behavior that should only happen after the input has stopped arriving. http://underscorejs.org/#debounce http://underscorejs.org/#debounce
- graue 13y agoThat bit from the Underscore docs is only a suggestion, and one that Google, for example, certainly doesn't follow. Try typing a search query so fast you don't get suggestions until you're finished. It's hard to do! Right after your quote, the docs add: "For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized..." These operations can both be very expensive on the client side — layout is slow — and can also distract the user if they make stuff jump around on the page. The downsides of doing these updates too often are more clear than for a simple autocomplete.
- graue 13y agoThanks for posting this. I'd written my own ad-hoc version of _.debounce for a web app, but the difference between throttle and debounce was totally lost on me. (If anyone else is slow today and doesn't immediately get it from reading the Underscore docs, there's a very clear comparison here[1].) Empirically, I can't type fast enough (sustained) for throttle to be better than debounce here — there are frequent 200ms gaps in my key presses. This is part of why I was confused. I thought I was typing very quickly, definitely faster than 43wpm == five keystrokes per second, but apparently I slow down to think now and then. My code seemed to behave like _.throttle already, but changing the timeout from 200ms to 2sec made it clear that it wasn't. But I'm switching to _.throttle, partly in case someone is a faster typist than me, and partly because it makes a leading-edge call, which may give a feeling of greater responsiveness. 1. http://drupalmotion.com/article/debounce-and-throttle-visual-explanation http://drupalmotion.com/article/debounce-and-throttle-visual...
- stefan_kendall 13y agoLibraries are the solution, +1. A handcoded solution to this would make me cry.
- gibbitz 13y agoWow. A library to wrap setinterval or settimeout? Given the use of "this" in his answer is painful, core JavaScript is already loaded and in IMO more maintainable than 3rd party libraries. In this thread alone there are arguments about what to use from the library. If I were the interviewer I wouldn't hire that answer either. I want a developer who can code his way out of a box, not ignore the box.