循环遍历setTimeout函数

时间:2015-08-24 13:47:08

标签: javascript jquery html for-loop settimeout

我正在尝试编写一个函数,该函数循环x次(本例中为3)x步(本例中的步骤1,步骤2)x秒(在本例中,步骤1需要2秒,步骤2需要1秒钟)。

所以我希望循环如下:

第1步(2秒) 第2步(1秒) 第1步(2秒) 第2步(1秒) 第1步(2秒) 第2步(1秒)

我已经得到了以下代码,但它只迭代循环一次,我无法解决原因。

jQuery('input').click(function () {
    for(i = 0; i < 3; i++){
        jQuery('div').html('Step 1');
        setTimeout(function() { 
            jQuery('div').html('Step 2');
        },2000);
        setTimeout(function() { 
            jQuery('div').empty();
        },2000 + 1000);
    }
});

我希望循环继续使用相同的时间,但在它到达.empty();后返回到开头。

JSFiddle:http://jsfiddle.net/kmyjhgvd/

5 个答案:

答案 0 :(得分:2)

循环迭代3次,但超时总是相同的:2000和3000,所以你创建了3个相同的回调,在2秒内执行,其他3个在3秒内被调用。在这里你有你想要的,有6种不同的超时:

http://jsfiddle.net/nsg7ny7L/1/

jQuery('input').click(function () {
    var time=0;
    for(i = 0; i < 3; i++){
        setTimeout(function() { 
            jQuery('div').html('Step 1');
        },time++*1000);
        setTimeout(function() { 
            jQuery('div').html('Step 2');
        },time++*1000);
    }
    setTimeout(function() { 
        jQuery('div').empty();
    },time++*1000);
});

PS:确保你理解它是如何工作的:JS是单线程的,所以for循环连续6次调用setTimeout ...所有这些的开始时间几乎相同

答案 1 :(得分:1)

我没有尝试过代码,但我认为这应该可行

jQuery('input').click(function () {
     loopAction (3, 1, 2); // x is number of loops - s1, s2 in seconds
});

function loopAction(x, s1, s2){
   If (x>0){                 // as long as x>0 start the iteration
      jQuery('div').html('Step 1');
      setTimeout(function() { 
          jQuery('div').html('Step 2');
          setTimeout(function() {
             loopAction(x-1, s1, s2); // recursive call to self
          }, s2*1000);
      },s1*1000);
  } else {
     jQuery('div').empty();    // x>0 is false
  }
}

答案 2 :(得分:0)

递归方法回答:

function recursiveSteps(config) {
    var _step = config.step;
    config.step++;

    jQuery('div').html('Step 1');
    setTimeout(function() { 
        jQuery('div').html('Step 2');
    },2000);
    setTimeout(function() { 
        jQuery('div').empty();
        },3000);
    if(config.step < 3) setTimeout(function() {recursiveSteps(config);}, config.step*1000);
    //you could put an "end" step here if needed

}

jQuery('input').click(recursiveSteps);

答案 3 :(得分:0)

jQuery('input').click(function () {

    var times = 0,
        printStep1 = function(){
            JQuery('div').html('Step 1');
            setTimeout( printStep2, 1000 );
        },
        printStep2 = function(){
            JQuery('div').html('Step 2');
            if( times++ < 3 ) setTimeout( printStep1, 1000 );
        };

    printStep1();
});

没有JQuery:

document.querySelector('input').addEventListener( "click", function () {

    var times = 0,
        printStep1 = function(){
            document.querySelector('div').innerHTML = 'Step 1';
            setTimeout( printStep2, 1000 );
        },
        printStep2 = function(){
            document.querySelector('div').innerHTML = 'Step 2';
            if( times++ < 3 ) setTimeout( printStep1, 1000 );
        };

    printStep1();
});

答案 4 :(得分:0)

使用超时连续执行步骤列表的通用方法:

var steps = [
    {
        timeout: 2000,
        action: function() { jQuery('div').html('Step 1'); },
    },
    {
        timeout: 1000,
        action: function() { jQuery('div').html('Step 2'); },
    },
    {
        timeout: 1000,
        action: function() { jQuery('div').empty(); },
    }
];

function executeSteps(times, index) {
    index = index || 0;
    var task = steps[index];
    if(index > 0 || times > 0) {
        if(index == 0) times--;
        task.action();
        setTimeout(function() { 
            executeSteps(times, (index + 1) % steps.length);
        }, task.timeout);
    }
}

jQuery('input').click(function () { 
    executeSteps(3);
});

JSFiddle