Calling setTimeout function within a loop

2020-02-07 04:16发布

问题:

I'm new to javascript and am trying to call a function using setTimeout from within a for loop. The loop executes for each member of a nodeList.

I'm finding that the function I'm calling with setTimeout is only actually executing during the last iteration of the loop. In the example below, I would like to make three separate calls to setTimeout but I'm finding that the first two calls are ignored.

function moveants(e, stepdistance) {

    . . . . .

    for(var i = 0; i < 3; i++)
    {
        var nextAnt = antgroup.childNodes[i]
        nextAnt.count = 0;
        nextAnt.member = i;
        setTimeout(function () { takeStep(nextAnt, mouseclickX, mouseclickY, 10) }, 0);
    }
}

function takeStep(ant, destX, destY, stepDistance) {

    . . . .

    . . . .

    if( condition )
    {
        return;
    }
    else
    {
        takeStep(ant, destX, destY, stepDistance);
    }
}

I have seen other posts that describe making multiple calls to setTimeout. Amazingly (to me), the multiple calls will work if I simply take them out of the for loop like this.

    setTimeout(function () { takeStep(antgroup.childNodes[0], 
         mouseclickX, mouseclickY, 10) }, 10);
    setTimeout(function () { takeStep(antgroup.childNodes[1], 
         mouseclickX, mouseclickY, 10) }, 10);
    setTimeout(function () { takeStep(antgroup.childNodes[2], 
         mouseclickX, mouseclickY, 10) }, 10);

I just can't figure out why there is a difference between calling them from within a for loop and calling them outside of one.

I am getting valid return values from the setInterval call in every case.. it's just that with only the last iteration of the for loop does the function actually execute.

Thanks in advance for any help.

回答1:

nextAnt will be overwritten on every loop, so takeStep() will be called 3 times, but always with the same arguments.

You may try this instead:

(function(a,b,c){
     setTimeout(function(){
                           takeStep(a,b,c,10)}, 0);
      })(nextAnt, mouseclickX, mouseclickY);


回答2:

If your not setting a delay, then why bother with setTimeout?

In the loop your delay is set to 0, outside the loop you've used 10. Also, outside the loop you've assigned values to count and member, but not outside the loop?

Try this:

function moveants(e, stepdistance)
{
    for (var i = 0; i < 3; i++)
    {
        setTimeout("takeStep(antgroup.childNodes[i], mouseclickX, mouseclickY, 10)", 0);
    }
}

or this:

function moveants(e, stepdistance)
{
    for (var i = 0; i < 3; i++)
    {
        takeStep(antgroup.childNodes[i], mouseclickX, mouseclickY, 10);
    }
}