Search code examples
javascriptfunctiontiming

Delay function from running for n seconds then run it once. (2minute question)


TLDR I have a function that runs on the end of a pan in an openlayers map. Don't want it to fire continously.


I have a function that runs on the end of panning a map. I want it so that it will not fire the function until say 3 secconds after the pan has finished. Although I don't want to queue up the function to fire 10 or so times like setTimeout is currently doing.

How can I delay a function from running for n seconds then run it only once no matter how many times it has been called?

    map.events.register("moveend", map, function() {
      setTimeout(SetLocation, 5000);
    });

Moveend:

moveend - triggered after a drag, pan, or zoom completes

The code above even using setTimeout(func, delay); still fires multiple times when it runs. How can I prevent this?



Solution

  • Well, meeting your requirements, you could build a simple function wrapper:

    var executeOnce = (function (fn, delay) {
      var executed = false;
      return function (/* args */) {
        var args = arguments;
        if (!executed) {
          setTimeout(function () {
            fn.apply(null, args); // preserve arguments
          }, delay);
          executed = true;
        }
      };
    });
    

    Usage examples:

    With your code:

    map.events.register("moveend", map, executeOnce(SetLocation, 5000));
    

    Other usages:

    var wrappedFn = executeOnce(function (a, b) {
      alert(a + ' ' + b);
    }, 3000);
    
    wrappedFn('hello', 'world');
    wrappedFn('foo', 'bar'); // this won't be executed...
    

    The wrapped function will be delayed the specified amount of time and executed only once.