Есть ли способ периодически вызывать функцию в JavaScript?

Ответы:

215

Вы хотите setInterval():

var intervalID = setInterval(function(){alert("Interval reached");}, 5000);

Первый параметр setInterval () также может быть строкой кода для оценки.

Вы можете очистить периодическую функцию с помощью:

clearInterval(intervalID);
zombat
источник
15
Я проголосовал за, а затем решил отменить свой голос за (но не против), потому что вы используете строковый аргумент для setInterval. Функции почти всегда следует использовать в пользу строкового аргумента для эффективности, безопасности и для их функций закрытия.
Jason S
5
Ничего страшного, я не против. setInterval()- правильный ответ на вопрос независимо от параметра. Это просто пример, и оба метода верны по определению.
zombat 03
2
Я согласен с Джейсоном С. это действительно должна быть функция. В вашем примере единственная проблема - это незначительная потеря производительности, но это плохая привычка.
Мэтью Крамли,
4
Я согласен с вами обоими, лучше использовать функцию. Я никогда не говорил, что это не так. В любом случае это правильно, но ради комментариев я отредактирую ответ, чтобы вместо этого он содержал функцию.
zombat 03
37

Обратите внимание, что setInterval () часто не лучшее решение для периодического выполнения - это действительно зависит от того, какой javascript вы действительно периодически вызываете.

например. Если вы используете setInterval () с периодом 1000 мс и в периодической функции вы делаете вызов ajax, который иногда занимает 2 секунды для возврата, вы сделаете еще один вызов ajax до того, как вернется первый ответ. Обычно это нежелательно.

Во многих библиотеках есть периодические методы, которые защищают от ловушек наивного использования setInterval, таких как пример Prototype, приведенный Нельсоном.

Чтобы добиться более надежного периодического выполнения с функцией, в которой есть вызов jQuery ajax, рассмотрите что-то вроде этого:

function myPeriodicMethod() {
  $.ajax({
    url: ..., 
    success: function(data) {
      ...
    },
    complete: function() {
      // schedule the next request *only* when the current one is complete:
      setTimeout(myPeriodicMethod, 1000);
    }
  });
}

// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);

Другой подход - использовать setTimeout, но отслеживать истекшее время в переменной, а затем динамически устанавливать задержку тайм-аута для каждого вызова, чтобы выполнить функцию как можно ближе к желаемому интервалу, но никогда не быстрее, чем вы можете получить ответ.

Мэтт Коубро
источник
setTimeout (myPeriodicMethod, 1000); называется 2 раза. это обязательно? Я думаю, что установленный тайм-аут должен вызываться только в полной функции
Вишнудев К.
1
Да, второй setTimeout () не является требованием, вы можете просто вызвать myPeriodicMethod (), который немедленно выполнит первый вызов ajax ... но если вы хотите запланировать его с задержкой с самого первого вызова, вы можете написать его как Я написал.
Мэтт Коубро
16

У всех уже есть решение setTimeout / setInterval. Я думаю, что важно отметить, что в setInterval можно передавать функции, а не только строки. На самом деле, вероятно, немного «безопаснее» передавать реальные функции вместо строк, которые будут «преобразованы» в эти функции.

// example 1
function test() {
  alert('called');
}
var interval = setInterval(test, 10000);

Или:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
gnarf
источник
3
+1 Если вы студент школы JavaScript Крокфорда , вы избегаете eval во всех его злых формах.
Патрик МакЭлхейни,
@Patrick - Я не думаю, что предложение «Не использовать $ (знак доллара) или \ (обратную косую черту) в именах» хорошо согласуется с лотом jQuery :)
Расс Кэм
6

Старый вопрос, но .. Мне также нужен был периодический бегун задач и написал TaskTimer . Это также полезно, когда вам нужно запускать несколько задач с разными интервалами.

// Timer with 1000ms (1 second) base interval resolution.
var timer = new TaskTimer(1000)

// Add task(s) based on tick intervals.
timer.addTask({
    name: 'job1',       // unique name of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (set to 0 for unlimited times)
    callback: function (task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
    }
});

// Start the timer
timer.start();

TaskTimerработает как в браузере, так и в Node. См. Документацию обо всех функциях.

Онур Йылдырым
источник
2
function test() {
 alert('called!');
}
var id = setInterval('test();', 10000); //call test every 10 seconds.
function stop() { // call this to stop your interval.
   clearInterval(id);
}
Бен Леш
источник
1

Поскольку вы хотите, чтобы функция выполнялась периодически , используйте setInterval

CMS
источник
1

Собственный способ - действительно setInterval()/ clearInterval(), но если вы уже используете библиотеку Prototype, вы можете воспользоваться PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Это предотвращает наложение вызовов. Из http://www.prototypejs.org/api/periodicalExecuter :

"он защищает вас от многократного параллельного выполнения функции обратного вызова, если для выполнения требуется больше заданного интервала (он поддерживает внутренний флаг" выполнения ", который защищен от исключений в функции обратного вызова). Это особенно полезно, если вы используйте один для взаимодействия с пользователем через заданные промежутки времени (например, используйте подсказку или вызов для подтверждения): это позволит избежать множественных окон сообщений, ожидающих выполнения действий ».

нельсон
источник