2015-08-29 2 views
0

Я пытаюсь непрерывно прокручивать массив значений чисел, которые будут переданы функции 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(); 

}); 

Я хотел бы иметь функцию огнь изменения непрерывно в различном запаздывающий раз. Прямо сейчас время не кажется правильным, когда я запускаю его. Любые предложения приветствуются. Благодаря!

+1

Что именно не за работой? Опишите ваши ожидания и фактические результаты. –

+0

В соответствии с числами в массиве синхронизации я ожидаю, что функция изменения будет срабатывать непрерывно каждые 5, 10, 17, 8, 14 и т. Д. Секунд. Исход сейчас состоит в том, что текст в теге p меняется, но не в эти интервалы. Я подозреваю, что моя функция удерживается на предыдущих интервалах. –

+0

Это то, что я имел в виду - вы повторяете одну и ту же функцию снова и снова, поэтому, конечно, вы действительно можете иметь эти интервалы, но впечатление обманчиво. –

ответ

1

В любом случае, с помощью цикла не будет работать, потому что многие из setInterval (или setTimeout()) «мгновенно» запускаются в течение нескольких микросекунд.
Таким образом, они выполняют свою работу, как указано их собственным 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(); 
}); 
+0

Вау, это очень полезно! Большое спасибо за объяснение и скрипку. Очень признателен. –

1

Просто увеличьте переменную i внутри функции setInterval.

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

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

    } 
} 
1

использование setTimeout вместо setInterval, потому что вы делаете это в цикле. setInterval будет инициализировать таймер, который непрерывно срабатывает с указанной задержкой (например, если задержка, если 5 секунд, она срабатывает при 5, 10, 15 и так далее). Используя setTimeout в вашей итерации, таймер срабатывает только один раз на итерацию после указанной задержки, а следующая итерация инициализирует новый таймер для следующего значения задержки.

+0

Правильно, я тоже попробовал setTimeout, но могу ли я непрерывно прокручивать массив, используя его? Как только цикл закончен, мне нужно, чтобы он начал снова. Благодарю. –

1

Предполагаете, что вы не можете очищать старые интервалы, как вы звоните setInterval. В соответствии с https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval вам может потребоваться очистить предыдущие интервалы с помощью clearInterval. Особенно, если вы используете один и тот же метод для всех своих интервалов, я думаю, вы можете не получить то, что хотите. Итак:

  1. Создать интервал, сохранить текущий идентификатор глобально
  2. Когда обратный вызов вызывается, очистить текущий интервал с помощью clearInterval функции
  3. Repeat
Смежные вопросы