Created
April 11, 2012 22:05
-
-
Save jhickner/2363070 to your computer and use it in GitHub Desktop.
underscore.js -> clojurescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn debounce [func wait immediate] | |
(let [timeout (atom nil)] | |
(fn [] | |
(this-as this | |
(let [context this | |
args js/arguments | |
later (fn [] | |
(reset! timeout nil) | |
(when-not immediate | |
(.apply func context args)))] | |
(if (and immediate (not @timeout)) | |
(.apply func context args)) | |
(js/clearTimeout @timeout) | |
(reset! timeout (js/setTimeout later wait))))))) | |
(defn throttle [func wait] | |
(let [result (atom nil) | |
throttling (atom nil) | |
more (atom nil) | |
timeout (atom nil) | |
when-done (debounce (fn [] | |
(reset! more false) | |
(reset! throttling false)) wait)] | |
(fn [] | |
(this-as this | |
(let [context this | |
args js/arguments | |
later (fn [] | |
(reset! timeout nil) | |
(when @more (.apply func context args)) | |
(when-done))] | |
(when-not @timeout | |
(reset! timeout (js/setTimeout later wait))) | |
(if @throttling | |
(reset! more true) | |
(reset! result (.apply func context args))) | |
(when-done) | |
(reset! throttling true) | |
@result))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Returns a function, that, when invoked, will only be triggered at most once | |
// during a given window of time. | |
_.throttle = function(func, wait) { | |
var context, args, timeout, throttling, more, result; | |
var whenDone = _.debounce(function(){ more = throttling = false; }, wait); | |
return function() { | |
context = this; args = arguments; | |
var later = function() { | |
timeout = null; | |
if (more) func.apply(context, args); | |
whenDone(); | |
}; | |
if (!timeout) timeout = setTimeout(later, wait); | |
if (throttling) { | |
more = true; | |
} else { | |
result = func.apply(context, args); | |
} | |
whenDone(); | |
throttling = true; | |
return result; | |
}; | |
}; | |
// Returns a function, that, as long as it continues to be invoked, will not | |
// be triggered. The function will be called after it stops being called for | |
// N milliseconds. If `immediate` is passed, trigger the function on the | |
// leading edge, instead of the trailing. | |
_.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); | |
}; | |
if (immediate && !timeout) func.apply(context, args); | |
clearTimeout(timeout); | |
timeout = setTimeout(later, wait); | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just created a fork with my attempt at a slightly more concise version of debounce (not looked at throttle).
See what you think, not sure if i've lost some functionality...