遍历数组并延迟函数

Looping through an array and delaying a function

我正在尝试连续遍历一个数值数组,这些数值将作为触发另一个函数的延迟值传递给 setInterval 函数。这是我拥有的:

HTML:

<p>On</p>

JavaScript:

$(document).ready(function(){
    var timing = [5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000, 7000, 17000, 8000, 13000, 12000, 18000]
    //function to change
    function change(){
            var p = $("p").html();
            if(p === "On"){
                $("p").html("Off"); 
            } else {
                $("p").html("On");
            }
        }


    function myFunction(){
        for (var i = 0; i < timing.length; i++){
            var switchTime = timing[i];

            setInterval(function(){
                change(); 

            },switchTime);

        }
    } myFunction();

});

我想让更改函数在不同的延迟时间连续触发。现在我 运行 的时间似乎不正确。任何建议表示赞赏。谢谢!

只需在 setInterval 函数中增加变量 i

function myFunction(){
    for (var i = 0; i < timing.length; ){
        var switchTime = timing[i];

        setInterval(function(){
            change(); 
           i++;
        },switchTime);

    }
}

使用 setTimeout 而不是 setInterval 因为您是在循环中执行此操作。 setInterval 将初始化一个定时器,该定时器在指定的延迟时连续触发(例如,如果延迟 5 秒,它将在 5、10、15 等时触发)。通过在 迭代 中使用 setTimeout,定时器在指定延迟后每次迭代仅触发一次,下一次迭代为下一个延迟值初始化一个新定时器。

我假设您在调用 setInterval 时可能不会清除旧间隔。根据 https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval,您可能需要使用 clearInterval 清除之前的间隔。特别是如果您对所有时间间隔都使用相同的方法,我认为您可能得不到想要的结果。所以:

  1. 创建区间,全局保存当前ID
  2. 当您的回调被调用时,使用clearInterval函数清除当前间隔
  3. 重复

无论如何,使用循环是行不通的,因为很多setInterval(或setTimeout())都是"instantly"在几微秒内启动的。
所以他们按照他们自己的 timing[i] 所说的做他们的工作,但几乎是在同一时间!

相反,您必须在前一个步骤结束时启动每个步骤

这是一个工作示例(另见 this fiddle),我在其中添加了一些过程的视觉跟踪:

HTML:

<p id="on-off">On</p>
<p id="delay"></p>

Javascript:

$(document).ready(function(){
  var timing = [
    5000, 10000, 17000, 8000, 14000, 9000, 12000, 8000, 20000, 7000, 13000,
    7000, 17000, 8000, 13000, 12000, 18000
  ];
  function myFunction(i){
    i |= 0;
    if (i < timing.length - 1) {
      var switchTime = timing[i]
          $onOff = $('#onOff');
      $('#delay').html('i=' + i + ', delay=' + switchTime);
      $onOff.html($onOff.html() == 'On' ? 'Off' : 'On');
      setTimeout(
        function() {
          myFunction(i + 1);
        }, switchTime
      )
    } else {
      $('#delay').html('end');
    }
  }
  myFunction();
});