diff --git a/test/functions.js b/test/functions.js index 230ebea9a..88ee2e73d 100644 --- a/test/functions.js +++ b/test/functions.js @@ -98,6 +98,15 @@ $(document).ready(function() { setTimeout(debouncedIncr, 150); _.delay(function(){ ok(counter == 1, "incr was debounced"); start(); }, 220); }); + + test("functions: once", function() { + var addBang = function(str) { return str + "!"; }; + hi = "Hi"; + hi2 = _.once(addBang, hi); + hi3 = _.once(addBang, hi); + equals(hi2, "Hi!"); + equals(hi3, undefined); + }); test("functions: wrap", function() { var greet = function(name){ return "hi: " + name; }; diff --git a/underscore.js b/underscore.js index 5aaaca372..9f05b3ec9 100644 --- a/underscore.js +++ b/underscore.js @@ -471,6 +471,17 @@ _.debounce = function(func, wait) { return limit(func, wait, true); }; + + // Runs a function only if it's never been run before. + _.once = function(func) { + if (_.indexOf(onceRunFunctions, func)) { + onceRunFunctions.push(func); + return func.apply(func, slice.call(arguments, 1)); + } + } + + // Internal record of functions that have been run via `_.once`. + var onceRunFunctions = []; // Returns the first function passed as an argument to the second, // allowing you to adjust arguments, run code before and after, and