Existe alguma maneira de chamar uma função periodicamente em JavaScript?

128

Existe alguma maneira de chamar uma função periodicamente em JavaScript?

coderex
fonte

Respostas:

214

Você quer setInterval():

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

O primeiro parâmetro para setInterval () também pode ser uma sequência de código a ser avaliada.

Você pode limpar uma função periódica com:

clearInterval(intervalID);
zombat
fonte
15
Fiz um voto positivo e, em seguida, decidi rescindir meu voto positivo (mas não negativo) porque você está usando um argumento de string para setInterval. As funções quase sempre devem ser usadas em favor de um argumento de string, para eficiência, segurança e para seus recursos de fechamento.
Jason S
5
Tudo bem, eu não me importo. setInterval()é a resposta correta para a pergunta, independentemente do parâmetro. É apenas um exemplo, e ambos os métodos estão corretos por definição.
zombat 03/08/09
2
Eu concordo com Jason S; realmente deveria ser uma função. No seu exemplo, o único problema é uma perda insignificante de desempenho, mas é um mau hábito entrar.
Matthew Crumley
4
Eu concordo com vocês dois, usar uma função é melhor. Eu nunca disse que não era. Está correto de qualquer maneira, mas, para efeitos dos comentários, editarei a resposta para conter uma função.
zombat 03/08/09
37

Observe que setInterval () geralmente não é a melhor solução para execução periódica - depende realmente de qual javascript você está chamando periodicamente.

por exemplo. Se você usar setInterval () com um período de 1000ms e na função periódica fizer uma chamada ajax que ocasionalmente leva 2 segundos para retornar, você fará outra chamada ajax antes que a primeira resposta volte. Isso geralmente é indesejável.

Muitas bibliotecas têm métodos periódicos que protegem contra as armadilhas do uso de setInterval de forma ingenuidade, como o exemplo de Prototype fornecido por Nelson.

Para obter uma execução periódica mais robusta com uma função que possui uma chamada ajax jQuery, considere algo como isto:

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);

Outra abordagem é usar setTimeout, mas rastrear o tempo decorrido em uma variável e, em seguida, definir o atraso de tempo limite em cada chamada dinamicamente para executar uma função o mais próximo possível do intervalo desejado, mas nunca mais rápido do que você pode obter respostas de volta.

Matt Coubrough
fonte
setTimeout (myPeriodicMethod, 1000); é chamado 2 vezes. é requerido? Acho set out deve ser chamado somente na função completa
Vishnudev K
1
Sim, o segundo setTimeout () não é um requisito, você pode simplesmente chamar myPeriodicMethod (), que executaria a primeira chamada ajax imediatamente ... mas se você deseja agendá-lo com um atraso desde a primeira chamada, você pode escrevê-lo como Eu tenho escrito.
precisa saber é o seguinte
16

Todo mundo já tem uma solução setTimeout / setInterval. Eu acho que é importante observar que você pode passar funções para setInterval, não apenas strings. Na verdade, é provavelmente um pouco "mais seguro" passar funções reais em vez de strings que serão "avaliadas" para essas funções.

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

Ou:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
gnarf
fonte
3
+1 Se você é um estudante da escola de JavaScript de Crockford , evita todas as formas de avaliação.
Patrick McElhaney
@Patrick - Eu não acho que o "Não use $ (cifrão) ou \ (barra invertida) em nomes de" sugestão vai cair bem com o lote jQuery :)
Russ Cam
6

Pergunta antiga, mas .. Eu também precisava de um executor de tarefas periódica e escrevi TaskTimer . Isso também é útil quando você precisa executar várias tarefas em intervalos diferentes.

// 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();

TaskTimerfunciona tanto no navegador quanto no nó. Consulte a documentação para todos os recursos.

Onur Yıldırım
fonte
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);
}
Ben Lesh
fonte
1

Como você deseja que a função seja executada periodicamente , use setInterval

CMS
fonte
1

A maneira nativa é de fato setInterval()/ clearInterval(), mas se você já estiver usando a biblioteca Prototype, poderá aproveitar o PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Isso evita a sobreposição de chamadas. Em http://www.prototypejs.org/api/periodicalExecuter :

"protege você contra várias execuções paralelas da função de retorno de chamada, caso demore mais do que o intervalo especificado para executar (mantém um sinalizador de" execução "interno, protegido contra exceções na função de retorno de chamada). Isso é especialmente útil se você use um para interagir com o usuário em intervalos determinados (por exemplo, use uma chamada rápida ou confirme): isso evitará várias caixas de mensagens aguardando para serem acionadas. "

Nelson
fonte