Vai SetInterval deriva?
-
13-09-2019 - |
Pergunta
Esta é uma pergunta realmente muito simples. Se eu usar setInterval(something, 1000)
, posso estar completamente certo de que depois de, digamos, 31 dias ele vai ter provocado "alguma coisa" tempos exatamente 60*60*24*31
? Ou há qualquer risco para a chamada deriva?
Solução
Aqui é um ponto de referência que você pode executar no Firefox:
var start = +new Date();
var count = 0;
setInterval(function () {
console.log((new Date() - start) % 1000,
++count,
Math.round((new Date() - start)/1000))
}, 1000);
Primeiro valor deve ser o mais próximo de 0 ou 1000 como possíveis (quaisquer outros shows de valor como "fora do lugar" o tempo do disparo era.) Segundo valor é o número de vezes que o código foi acionado, e terceiro valor é quantas vezes o poderia deve ter sido provocado. Você vai notar que, se você monopolizar o seu CPU pode ficar muito fora do local, mas parece corrigir-se. Tente executá-lo por um longo período de tempo e ver como ele lida.
Outras dicas
resposta curta: Não, você não pode ter certeza. Sim, ele pode deriva.
Resposta longa: John Resig na Precisão do JavaScript Tempo e < a href = "http://ejohn.org/blog/how-javascript-timers-work/" rel = "noreferrer"> Como JavaScript Timers Trabalho .
A partir do segundo artigo:
A fim de entender como os temporizadores trabalham internamente há um conceito importante que precisa ser explorado: o atraso do temporizador não é garantida. Uma vez que todos JavaScript em um navegador executa em um único segmento eventos assíncronos (como cliques do mouse e temporizadores) só são executados quando houve uma abertura na execução.
Os dois artigos (e qualquer coisa nesse site) é grande leitura, então têm-no.
(Desculpem o meu mau Inglês) I teve mesmo problema sobre a contagem de baixo função, i writed uma função de contagem decrescente () e laço com setInterval mas a sua deriva 1-3 milissegundos por laço. Então eu escrever uma função que controla há qualquer deriva e fixa-lo.
Ele controla com minuto real e em segundo lugar apenas. Aqui está. Sua funciona bem para mim, eu espero que isso irá ajudá-lo também.
$.syncInterval(functionname,interval,controlinterval)
exemplo:
countdown(){ some code };
$.syncInterval(countdown,1000,60);
diz função contagem regressiva prazo a cada 1000 milissegundos e verificá-lo a cada 60 segundos
aqui está o código:
$.syncInterval = function (func,interval,control) {
var
now=new Date();
realMinute=now.getMinutes(),
realSecond=now.getSeconds(),
nowSecond=realSecond,
nowMinute=realMinute,
minuteError=0,
countingVar=1,
totalDiff=0;
var loopthat = setInterval(function(){
if (nowSecond==0) {
nowMinute++;
nowMinute=nowMinute%60;
};
if (countingVar==0){
now=new Date();
realSecond=now.getSeconds();
realMinute=now.getMinutes();
totalDiff=((realMinute*60)+(realSecond))-((nowMinute*60)+(nowSecond));
if(totalDiff>0){
for (i=1;i<=totalDiff;i++) {
func();
nowSecond++;
countingVar++;
};
} else if (totalDiff==0){
func();
nowSecond++;
countingVar++;
} else if (totalDiff<0) {
};
} else {
func();
nowSecond++;
countingVar++;
};
countingVar=countingVar%control;
nowSecond=nowSecond%60;
},interval);
};