Pregunta ¿Establecerá driftInterval?


Esta es una pregunta bastante simple en realidad. Si uso setInterval(something, 1000), ¿puedo estar completamente seguro de que después de, digamos, 31 días habrá activado "algo" exactamente? 60*60*24*31 ¿veces? ¿O hay algún riesgo para la llamada deriva?


32
2018-06-12 08:53


origen


Respuestas:


Aquí hay un punto de referencia que puede ejecutar en Firefox:

var start = +new Date();
var count = 0;
setInterval(function () {
    console.log((new Date() - start) % 1000,
    ++count,
    Math.round((new Date() - start)/1000))
}, 1000);

El primer valor debe ser lo más cercano posible a 0 o 1000 (cualquier otro valor muestra cuán "fuera del lugar" era el momento del disparo). El segundo valor es el número de veces que se ha activado el código, y el tercer valor es cuántas veces el podría debería han sido disparados Notarás que si acaparas tu CPU puede salir del lugar, pero parece corregirse solo. Intente ejecutarlo por un período de tiempo más largo y vea cómo lo maneja.


17
2018-06-12 09:04



Respuesta corta: No, no puedes estar seguro. Sí, puede derivar.

Larga respuesta: John Resig en el Precisión del tiempo de JavaScript y Cómo funcionan los temporizadores de JavaScript.

Del segundo artículo:

Para comprender cómo funcionan los temporizadores internamente, hay un concepto importante que debe explorarse: el retraso del temporizador no está garantizado. Como todo el JavaScript de un navegador se ejecuta en un solo subproceso, los eventos asincrónicos (como los clics y los clics del mouse) solo se ejecutan cuando ha habido una apertura en la ejecución.

Ambos artículos (y cualquier cosa en ese sitio) son de gran lectura, así que ten cuidado.


28
2018-06-12 08:56



(Perdón por mi mal inglés) Tuve el mismo problema con la función de conteo regresivo, escribí una función de cuenta atrás () y un bucle con setInterval, pero está a la deriva de 1-3 milisegundos por ciclo. Luego escribo una función que controla si hay deriva y la solucioné.

Controla con minutos reales y segundos solamente. Aquí está. Me funciona bien, espero que te ayude también.

$.syncInterval(functionname,interval,controlinterval)

ejemplo:

countdown(){ some code };
$.syncInterval(countdown,1000,60);

dice ejecutar la función de cuenta atrás cada 1000 milisegundos y verificarlo cada 60 segundos

aquí está el 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);
};

1
2018-04-29 00:09