setInterval not call function with arguments

2019-08-31 17:50发布

I was trying to repeatedly call a function using setInterval. When I call a function without arguments, it works. However, on calling a function with arguments, the function is called only once.

Here is the js fiddle

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<script src="./check.js">

</script>
</body>
</html>

check.js Without arguments - works

setInterval(myfun,100)
var mycounter = 0;

function myfun()
{
    console.log(mycounter++)
}

check.js With arguments - does not work

setInterval(myfun(0),1000)

function myfun(mycounter)
{
    console.log(mycounter++)
}

3条回答
一夜七次
2楼-- · 2019-08-31 18:24

Working Fiddle: https://jsfiddle.net/0tesf2rk/

var counter = {

  value: 0,

  increase: function () {

    console.log(counter.value);

    counter.value++;

  }

};

counter.value = 20;

setInterval(counter.increase, 1000);
查看更多
▲ chillily
3楼-- · 2019-08-31 18:33

When you add the parentheses the function is called right away, and the returned result is used in the interval, which in your case is the default return value of undefined.

What you're really doing is

var result = myfun(0); // returns undefined

setInterval(result, 1000); // no go, result is undefined

function myfun(mycounter) {

}

if you want to pass arguments, the easiest is to just use an anonymous function

setInterval(function() {
    myfun(0);
}, 1000);

Modern browser (not IE9 and below) now support passing arguments directly in setInterval

setInterval(myfun, 1000, 0); // "0" is passed as the first argument to myfun()

of course, incrementing the variable can only be done if the variable exists in a scope outside the callback function for the interval

查看更多
smile是对你的礼貌
4楼-- · 2019-08-31 18:41

right...

what setInterval wants is a function that it can call,

in the first case you are providing the function

in the second case you are calling the function and then returning its value

to accomplish what you are trying to do in the second case you would do this:

setInterval(function() {myFun(20)}, 1000} 

which creates a NEW function that wraps your call to myFun inside it... comprehend?

Now the other thing to keep in mind is that setInterval keeps calling the function forever until you stop it.... so you could do this:

var counter = 20;
setInterval(function() {counter = counter-1; if (counter > 0) myFun()}, 1000)

which will call myFun every second until counter expires...

But this is still not perfect a the interval will keep running forever so what you want is something like this (its a working example, click the run button at the bottom)

    function nTimes(fn, count, time) {
      var interval = setInterval(function() {
        if (count > 0) {
          count = count - 1;
          fn(count);
        } else {
          clearInterval(interval);
        }
      }, time)
    };


    function myFun(x) {
      $('#output').html($('#output').html() + x + '</br>')
    }
    nTimes(myFun, 20, 1000)
<div id='output'></div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

查看更多
登录 后发表回答