Design & Download
Your JS Library
in Seconds!!!

Snippet: limit() - Limiting Function Calls

Written by Christopher West (cwest) on November 07, 2015.
Creates a new copy of the function passed in which can only be called a limited amount of times.
function limit(fn, opt_callLimit, opt_throwError) {
  opt_callLimit = opt_callLimit == undefined ? 1 : opt_callLimit;
  return function() {
    if (0 < opt_callLimit--) {
      return fn.apply(this, arguments);
    }
    if (opt_throwError) {
      throw new Error('Limited function called too many times.');
    }
  }
}

At times when dealing with functions that will be bound to an element you may need to prevent that function from being run multiple times. In order to do that you could use a JavaScript library such as jQuery and bind the function with the jQuery#one function. Of course, if you want a stripped down library that only has this and other functions that you or other devs write, you can add this YourJS snippet to your build.

Example

Now that we have the definition for this limit function we can learn how to use it by example:

// Encapsulate data so the user cant cheat.
(function() {
  // Function to greet the user.
  var sayHello = limit(function(name) {
    alert('Hello ' + name + '!!!');
  });

  // Ask for the user's name.
  var userName = prompt('What is your name?', 'user');

  // Greet the user.
  sayHello(userName);

  // Try greeting the user again... this should fail.
  sayHello(userName);

  // Generate a random number from 1 to 10.
  var randomNumber = parseInt(Math.random() * 10) + 1;

  // A function which will only allow the user to make 3 guesses.  After
  // 3 guesses, subsequent calls will cause an error to be thrown.
  var makeGuess = limit(function(previousGuess) {
    return prompt('Guess a number between 1 and 10:', previousGuess);
  }, 3, true);

  // Play the guessing game.
  var guess = '';
  try {
    while(+(guess = makeGuess(guess)) != randomNumber) {
      if(guess &lt; randomNumber) {
        alert('Nope, it is higher than that.');
      }
      else {
        alert('Nope, it is lower than that.');
      }
    }
    alert('You got it!!!');
  }
  catch(e) {
    alert('Unfortunately you hit your limit.\n'
      + 'The number I was thinking of was ' + randomNumber + '.');
  }
})();

You can click here to see the result of running the two preceeding blocks of code. Note that the greeting only appears once, even though it is in the code twice. Also notice that the try-catch clause is used to determine when the user tries to make another guess but the maximum amount of guesses have already been made.

Function Description

This limit function creates a new copy of the function passed in which can only be called a limited amount of times.

Parameters

  1. fn {Function}:
    The function which will only be called a limited amount of times.
  2. opt_callLimit {number}:
    Optional. Defaults to 1. The maximum amount of times the returned wrapper function can be called before producing an error.
  3. opt_throwError {boolean}:
    Optional. Defaults to false. If true is specified an error will be thrown if the amount of calls is exceeded. Otherwise the error will simply be returned.

Returns

Returns a new wrapper function so that the context and the parameters passed to this wrapper function will be passed to fn iff opt_callLimit hasn't been exceeded.

Final Notes

Personally I would think this is most useful for event handling but if you have anymore uses for it please let us know.