3

How to call a function 10 times like

for(x=0; x<10; x++) callfunction();

but with 1 sec between each call?

user3129452
  • 65
  • 1
  • 1
  • 6

8 Answers8

14
function callNTimes(func, num, delay) {
    if (!num) return;
    func();
    setTimeout(function() { callNTimes(func, num - 1, delay); }, delay);
}
callNTimes(callfunction, 10, 1000);

EDIT: The function basically says: make a call of the passed function, then after a bit, do it again 9 more times.

Amadan
  • 191,408
  • 23
  • 240
  • 301
13

You can use setInterval for repeated execution with intervals and then clearInterval after 10 invocations:

callfunction();
var callCount = 1;
var repeater = setInterval(function () {
  if (callCount < 10) {
    callfunction();
    callCount += 1;
  } else {
    clearInterval(repeater);
  }
}, 1000);

Added: But if you don't know how long it takes your callfunction to execute and the accurate timings between invocation starting points are not important it seems it's better to use setTimeout for reasons mentioned by Paul S and those described in this article.

aemxdp
  • 1,348
  • 1
  • 14
  • 34
  • 2
    I would advise against using `setInterval` especially when you don't know how long `callfunction` will take to finish invoking (more important if code is re-used for less-than-1-second intervals), as you can end up with nasty.. cascades? – Paul S. Feb 08 '14 at 16:27
  • @PaulS. Hm, you're right. I've found related article, and now agree that in general case setTimeout seems to be more appropriate. Though, there may be cases when accurate timings between invocation starting points are more important (and when it takes (0,1] seconds to finish). – aemxdp Feb 08 '14 at 16:42
6

Another solution

for(var x=0; x<10; x++) window.setTimeout(callfunction, 1000 * x);
HenningCash
  • 2,030
  • 18
  • 17
4

You can try to use setInterval and use a variable to count up to 10. Try this:

var number = 1;
function oneSecond () {
  if(number <= 10) {
    // execute code here..
    number++;
  }
};

Now use the setInterval:

setInterval(oneSecond, 1000);
Tucker Flynn
  • 15
  • 2
  • 10
Afzaal Ahmad Zeeshan
  • 15,669
  • 12
  • 55
  • 103
2

I don't know if there's a proper name, but I use a repeater:

function Repeater(callback, delay, count) {
    var self = this;
    this.timer = setTimeout(function() {self.run();},delay);
    this.callback = callback;
    this.delay = delay;
    this.timesLeft = count;
    this.lastCalled = new Date().getTime();
}
Repeater.prototype.run = function() {
    var self = this;
    this.timesLeft--;
    this.callback();
    this.lastCalled = new Date().getTime();
    if( this.timesLeft > 0) {
        this.timer = setTimeout(function() {self.run();},this.delay);
    }
}
Repeater.prototype.changeDelay = function(newdelay) {
    var self = this;
    clearTimeout(this.timer);
    this.timer = setTimeout(function() {self.run();},
                          newdelay-new Date().getTime()+lastcalled);
    this.delay = newdelay;
}
Repeater.prototype.changeCount = function(newcount) {
    var self = this;
    if( this.timesLeft == 0) {
        this.timer = setTimeout(function() {self.run();},this.delay);
    }
    this.timesLeft = newcount;
    if( this.timesLeft == 0) clearTimeout(this.timer);
}

You can then use it like this:

new Repeater(callfunction, 1000, 10); // 1 second delay, 10 times
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • This won't actually work properly because when `run()` is called by `setTimeout()`, the `this` value will not point to the Repeater object. You would have to use a closure or `.bind()` to fix. – jfriend00 Feb 08 '14 at 16:16
  • @jfriend00 Eeeehhhh... if you need to refer to the Repeater itself, I just have `var rpt = new Repeater(function() { doSomethingWith(rpt); }, delay, conut);` – Niet the Dark Absol Feb 08 '14 at 16:16
  • Perhaps you didn't understand my comment? When you pass this.run to `setTimeout()` all that gets saved by `setTimeout()` is the function reference to `run()` and it is NOT called with the proper `this` value so your code will not work. – jfriend00 Feb 08 '14 at 16:24
  • Ah, I see what you mean. My mistake. – Niet the Dark Absol Feb 08 '14 at 16:24
  • You could just use `self.run()` in your function stub instead of `self.run.call(this);`. – jfriend00 Feb 08 '14 at 16:28
2

Similar to Amadan's answer but with a different style of closure which means you re-use instead of creating new functions

function call(fn, /* ms */ every, /* int */ times) {
    var repeater = function () {
        fn();
        if (--times) window.setTimeout(repeater, every);
    };
    repeater(); // start loop
}
// use it
var i = 0;
call(function () {console.log(++i);}, 1e3, 10); // 1e3 is 1 second
// 1 to 10 gets logged over 10 seconds

In this example, if you were to set times to either 0 or Infinity, it would run forever.

Community
  • 1
  • 1
Paul S.
  • 64,864
  • 9
  • 122
  • 138
0

const functionCounterTimer = (callCount) => {
  if (callCount < 10) {
    setTimeout(() => {
      ++callCount
      console.log("Function Call ", callCount);
      functionCounterTimer(callCount);
    }, 1000);
  }
}

functionCounterTimer(0);

The above was my approach to a similar question.

-1
setInterval(function(){},1000);

Calls the function for every second...

You can also use setTimeout for your thing to work.