Pergunta

Tanto quanto eu posso dizer, esses dois pedaços de javascript se comportam da mesma maneira:

Opção A:

function myTimeoutFunction()
{
    doStuff();
    setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

Opção B:

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

Existe alguma diferença entre usar setTimeout e setInterval ?

Foi útil?

Solução

Eles essencialmente tentar fazer a mesma coisa, mas a abordagem setInterval será mais preciso do que a abordagem setTimeout, desde setTimeout aguarda 1000ms, executa a função e, em seguida, define outro timeout. Assim, o período de espera é realmente um pouco mais de 1000 ms (ou muito mais se a sua função leva um longo tempo para executar).

Altough se poderia pensar que setInterval irá executar exatamente cada 1000ms, é importante notar que setInterval também irá atraso, uma vez que o JavaScript não é uma linguagem multi-threaded, o que significa que - se houver são outras partes do script em execução - o intervalo vai ter que esperar para que ao fim

.

Na este violino, você pode ver claramente que o tempo limite vai cair para trás, enquanto o intervalo é quase todo o tempo em quase 1 chamada / segundo (qual o script está tentando fazer). Se você alterar a variável de velocidade na parte superior para algo pequeno como 20 (ou seja, ele vai tentar correr 50 vezes por segundo), o intervalo será nunca se atingir uma média de 50 iterações por segundo.

O atraso é quase sempre insignificante, mas se você está programando algo realmente precisa, você deve ir para um auto-ajustável temporizador (que é essencialmente um temporizador baseado em tempo limite que constantemente ajusta-se para o atraso é criado)

Outras dicas

Existe alguma diferença?

Sim. A Timeout executa um determinado período de tempo após setTimeout () é chamado; um intervalo executa um determinado período de tempo após o intervalo anterior demitido.

Você vai notar a diferença se a sua função doStuff () leva um tempo para executar. Por exemplo, se nós representamos uma chamada para setTimeout / setInterval com ., um disparo do tempo limite / intervalo com * e JavaScript execução de código com [-----], os prazos parecido:

Timeout:

.    *  .    *  .    *  .    *  .
     [--]    [--]    [--]    [--]

Interval:

.    *    *    *    *    *    *
     [--] [--] [--] [--] [--] [--]

A próxima complicação é se um fogo de intervalo, enquanto JavaScript já está ocupado fazendo alguma coisa (como a manipulação de um intervalo anterior). Neste caso, o intervalo é lembrado, e acontece tão logo os acabamentos manipulador anteriores e retorna o controle para o navegador. Assim, por exemplo para um processo doStuff () que às vezes é curta ([-]) e, por vezes longo ([-----]):

.    *    *    •    *    •    *    *
     [-]  [-----][-][-----][-][-]  [-]

• representa um disparo intervalo que não pôde executar o seu código de imediato, e foi feito pendente vez.

Assim intervalos tentar ‘catch up’ para voltar à programação. Mas, eles não fila de um em cima do outro: não só pode ser sempre uma execução pendente por intervalo. (Se todos eles em fila, o navegador ficaria com uma lista cada vez maior de execuções pendentes!)

.    *    •    •    x    •    •    x
     [------][------][------][------]

x representa um disparo intervalo que não poderia executar ou ser feita pendente, então ao invés foi descartada.

Se o seu doStuff () função recebe habitualmente mais tempo para executar do que o intervalo que está definido para ele, o navegador vai comer 100% CPU tentando serviço dele, e pode tornar-se menos sensível.

O que você usa e por quê?

Chained-Timeout dá um slot garantido de tempo livre para o navegador; tentativas de intervalo para assegurar a função que está sendo executado é executado como próximo possível de seus horários programados, em detrimento da disponibilidade UI browser.

Eu consideraria um intervalo para one-off animações que eu queria ser o mais suave possível, enquanto o tempo limite acorrentados são mais educados para animações em curso que terá lugar o tempo todo, enquanto a página é carregada. Para usos (como um atualizador trivial disparando a cada 30 segundos ou algo assim) menos exigente, você pode usar com segurança também.

Em termos de compatibilidade do navegador, setTimeout antecede setInterval, mas todos os navegadores que você irá encontrar apoio hoje ambos. A última straggler por muitos anos foi IE Mobile em WinMo <6,5, mas espero que também está agora atrás de nós.

setInterval ()

setInterval() é um método de execução de código com base intervalo de tempo que tem a capacidade nativa de repetidamente executar um script especificado quando o intervalo é alcançado. Deve não ser aninhados em sua função de retorno de chamada pelo autor de script para torná-lo loop, uma vez que voltas por padrão . Ele vai manter a disparar contra o intervalo a menos que você chamar clearInterval().

Se você quiser código de loop para animações ou em um pulso de clock, em seguida, usar setInterval().

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);

setTimeout ()

setTimeout() é um método de execução de código baseado no tempo que irá executar apenas um script uma vez quando o intervalo é alcançado. Ele irá não repetir novamente a menos que você preparam-lo para repetir o script aninhando o setTimeout() objeto dentro da função que chama a correr. Se orientada para loop, ele vai manter a disparar contra o intervalo a menos que você chamar clearTimeout().

function doStuff() {
    alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);

Se você quer que algo aconteça uma vez após um determinado período de tempo, em seguida, usar setTimeout(). Isso é porque ele só executa uma vez quando o intervalo especificado for atingido.

O setInterval torna mais fácil para cancelar a execução futura do seu código. Se você usar setTimeout, você deve manter o controle do id temporizador no caso de você deseja cancelar mais tarde.

var timerId = null;
function myTimeoutFunction()
{
    doStuff();
    timerId = setTimeout(myTimeoutFunction, 1000);
}

myTimeoutFunction();

// later on...
clearTimeout(timerId);

contra

function myTimeoutFunction()
{
    doStuff();
}

myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);

// later on...
clearInterval(timerId);

I encontrar o método setTimeout mais fácil de usar se você quiser cancelar o tempo limite:

function myTimeoutFunction() {
   doStuff();
   if (stillrunning) {
      setTimeout(myTimeoutFunction, 1000);
   }
}

myTimeoutFunction();

Além disso, se algo desse errado na função que só vai parar de repetir no primeiro erro tempo, em vez de repetir o erro a cada segundo.

A própria diferença está em seus propósitos.

setInterval()
   -> executes a function, over and over again, at specified time intervals  

setTimeout()
   -> executes a function, once, after waiting a specified number of milliseconds

É tão simples como isso

detalhes mais elaborados aqui http://javascript.info/tutorial/settimeout-setinterval

Quando você executar alguma função dentro setInterval, que trabalha mais tempo do que timeout-> o navegador será preso.
Restaurant - por exemplo, doStuff () leva 1.500 sec. para ser executado e você faz: setInterval (doStuff, 1000);
1) run Navegador doStuff () que leva 1,5 segundos. para ser executado; Página 2) Depois de ~ 1 segundo que tenta executar doStuff () novamente. Mas anterior doStuff () é ainda executed-> tão navegador adiciona esta corrida para a fila (para executar após o primeiro é feito).
3,4, ..) O mesmo adicionando para a fila de execução para próximas iterações, mas doStuff () anteriores ainda estão em andamento ...
Como o result- o navegador está preso.

Para evitar esse comportamento, a melhor maneira é executar setTimeout dentro setTimeout para emular setInterval .
a limites de tempo corretas entre chamadas setTimeout, você pode usar auto-correção alternativa à técnica setInterval de JavaScript.

Eu uso setTimeout.

Aparentemente, a diferença é setTimeout chama o método uma vez, chamadas setInterval ele repeatdly.

Aqui está um bom artigo que explica a diferença: Tutorial: JavaScript temporizadores com setTimeout e setInterval

Eu fiz teste simples de setInterval(func, milisec), porque eu estava curioso o que acontece quando o consumo de tempo a função é maior do que a duração do intervalo.

setInterval vai em geral cronograma próxima iteração logo após o start da iteração anterior, a menos que a função ainda está em curso . Se assim for, setInterval vai esperar, até as extremidades de função. Assim que isso acontece, a função é imediatamente disparou novamente - não há espera para a próxima iteração acordo com a programação (como seria em condições sem função excedeu tempo). Não há também nenhuma situação com iterações paralelas em execução.

Eu testei isso em v23 Chrome. Espero que seja a execução determinística em todos os navegadores modernos.

window.setInterval(function(start) {
    console.log('fired: ' + (new Date().getTime() - start));
    wait();
  }, 1000, new Date().getTime());

saída do console:

fired: 1000    + ~2500 ajax call -.
fired: 3522    <------------------'
fired: 6032
fired: 8540
fired: 11048

A função wait é apenas um ajudante bloqueando fio - chamada ajax síncrono que leva exatamente 2500 milissegundos de processamento no lado do servidor:

function wait() {
    $.ajax({
        url: "...",
        async: false
    });
}

O código terá diferentes intevals de execução e, em alguns projectos, tais como jogos online não é aceitável. Em primeiro lugar, o que deve fazer, para fazer seu trabalho de código com os mesmos intevals, você deve mudar "myTimeoutFunction" a esta:

function myTimeoutFunction()
{
    setTimeout(myTimeoutFunction, 1000);
    doStuff();
}
myTimeoutFunction()

Após esta alteração, será igual a

function myTimeoutFunction()
{
    doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);

Mas, você ainda não resultado estável, porque JS é single-threaded. Por enquanto, se fio JS vai estar ocupado com alguma coisa, não será capaz de executar a sua função de retorno, e execução será adiada por 2-3 ms. É que você tem 60 execuções por segundo, e cada vez que você tem aleatório 1-3 segundos de atraso, será absolutamente não aceitável (após um minuto ele será em torno de 7200 atraso ms), e posso conselho para usar algo como isto:

    function Timer(clb, timeout) {
        this.clb = clb;
        this.timeout = timeout;
        this.stopTimeout = null;
        this.precision = -1;
    }

    Timer.prototype.start = function() {
        var me = this;
        var now = new Date();
        if(me.precision === -1) {
            me.precision = now.getTime();
        }
        me.stopTimeout = setTimeout(function(){
            me.start()
        }, me.precision - now.getTime() + me.timeout);
        me.precision += me.timeout;
        me.clb();
    };

    Timer.prototype.stop = function() {
        clearTimeout(this.stopTimeout);
        this.precision = -1;
    };

    function myTimeoutFunction()
    {
        doStuff();
    }

    var timer = new Timer(myTimeoutFunction, 1000);
    timer.start();

Este código vai garantir período de execução estável. fio, nem será ocupado, e seu código será executado após 1005 mseconds, da próxima vez ele terá tempo limite para 995 ms, eo resultado será estável.

Para olhar para ele um pouco diferente: Garante setInterval que um código é executado a cada determinado intervalo (ou seja 1000ms, ou quanto você especificar), enquanto setTimeout define o tempo em que 'espera até que' corre o código. E uma vez que leva milissegundos extras para executar o código, acrescenta-se a 1000ms e, assim, setTimeout é executado novamente, às vezes inexatas (mais de 1000 ms).

Por exemplo, temporizadores / contagens regressivas não são feitas com setTimeout, eles são feitos com setInterval, para garantir que ele não atrase e o código é executado no intervalo exato dado.

Ambos setInterval e setTimeout retornar um ID de temporizador que você pode usar para cancelar a execução, isto é, antes dos tempos de espera são acionados. Para cancelar você chamar qualquer clearInterval ou clearTimeout assim:

var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);

Além disso, os tempos de espera são cancelados automaticamente quando você deixar a página ou fechar a janela do navegador.

Bem, setTimeout é melhor em uma situação, como acabo de saber. Eu sempre uso setInterval, que eu deixei para executar em segundo plano por mais de meia hora. Quando eu mudei de volta a esse guia, a apresentação (em que foi usado o código) foi mudando muito rapidamente, em vez da cada 5 segundos que deveria ter. Ele, de fato, acontecer de novo como eu testá-lo mais e se é culpa do navegador ou não não é importante, porque com setTimeout que situação é completamente impossível.

Você pode validar resposta bobince por si mesmo quando você executar o seguinte javascript ou verificar este jsFiddle

<div id="timeout"></div>
<div id="interval"></div>

var timeout = 0;
var interval = 0;

function doTimeout(){
    $('#timeout').html(timeout);
    timeout++;
    setTimeout(doTimeout, 1);
}

function doInterval(){
    $('#interval').html(interval);
    interval++;
}

$(function(){
    doTimeout();
    doInterval();
    setInterval(doInterval, 1);
});

A diferença é óbvia no console:

enter descrição da imagem aqui

Apenas adicionando em que já foi dito, mas a versão setTimeout do código também vai chegar ao Maximum call stack size que irá parar de funcionar. Desde que não há nenhum caso de base para a função recursiva para parada em que você não pode tê-lo executado para sempre.

Eu acho SetInterval e SetTimeout são diferentes. SetInterval executa o bloco de acordo com o conjunto de tempo, enquanto, SetTimeout executa o bloco de código uma vez.

Tente este conjunto de códigos após os segundos de tempo limite de contagem regressiva:

setInterval(function(e){
    alert('Ugbana Kelvin');
}, 2000);

e tente

setTimeout(function(e){
    alert('Ugbana Kelvin');
}, 2000);

Você pode ver as diferenças para si mesmo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top