2011-09-14 15 views
19

Estoy usando la función setInterval() para llamar a una función cada 20 segundos. Sin embargo, una cosa que noté es que la primera vez que llama al setInterval() es a 20 segundos (y no cuando se llama a setInterval()). Aquí está mi solución actual:JavaScript: ¿Cómo obtener setInterval() para comenzar ahora?

dothis(); 
var i = setInterval(dothis, 20000); 

¿Hay alguna manera de lograr esto sin tener este código duplicado?

Respuesta

29

Su método es LA FORMA normal de hacerlo.

Si esto surge una y otra vez, usted podría hacer una función de utilidad que ejecutar el manejador primero y luego establecer el intervalo:

function setIntervalAndExecute(fn, t) { 
    fn(); 
    return(setInterval(fn, t)); 
} 

Luego, en su código, usted podría hacer esto:

var i = setIntervalAndExecute(dothis, 20000); 
+0

Información importante. ¡Gracias! – Andrew

2

Si su función dothis no tiene otra necesidad de un valor de retorno, puede hacer que regrese a sí mismo.

Esto le permitirá invocarlo y pasarlo al mismo tiempo. Si se ignora el valor de retorno, será inofensivo.

function dothis() { 
    // your code 
    return dothis; 
} 

var i = setInterval(dothis(), 20000); 

De lo contrario, se podría extender Function.prototype para dar una invocación y la funcionalidad de volver a todas sus funciones:

DEMO:http://jsfiddle.net/ZXeUz/

Function.prototype.invoke_assign = function() { 
    var func = this, 
     args = arguments; 
    func.call.apply(func, arguments); 
    return function() { func.call.apply(func, args); }; 
}; 

setInterval(dothis.invoke_assign('thisArg', 1, 2, 3), 20000); 

// thisArg 1 2 3 
// thisArg 1 2 3 
// thisArg 1 2 3 
// ... 

Esto mejora realmente las cosas un poco . Le permite pasar un conjunto de argumentos. El primer argumento establecerá el valor this de la función que invoca, y el resto de los argumentos se transmitirán como argumentos regulares.

Dado que la función devuelta está envuelta en otra función, tendrá un comportamiento idéntico entre las invocaciones iniciales y de intervalo.

10

Puede realizar una función anónima y llamarla de inmediato, excepto que utiliza la función setTimeout en lugar de setInterval.

(function doStuff() { 
    //Do Stuff Here 
    setTimeout(doStuff,20000); 
})(); 

Esto ejecutará la función y luego la volverá a llamar en 20 segundos.

Tenga en cuenta que, dependiendo del comportamiento que desee o, en algunos casos, del rendimiento, puede ser mejor utilizar setTimeout en setInterval. La principal diferencia es que setInterval llama a esa función cada vez que se agota el tiempo de espera, INDEPENDIENTEMENTE si la última llamada ha terminado de ejecutarse o si se produce un error. Usar setTimeout es que esta moda asegura que la función termine su ejecución antes de que el temporizador se reinicie. Muchas de las compensaciones son bastante evidentes, pero es algo bueno a tener en cuenta al diseñar su aplicación.

EDIT En respuesta a la preocupación de patrick dw sobre la necesidad de cancelar el tiempo de espera.La mejor solución es no utilizar la función anónima, y ​​simplemente llamarlo después de la declaración

var timeout; 
function doStuff() { 
    //doStuff 
    timeout = setTimeout(doStuff,20000); 
} 
doStuff() 

Sí esto es similar a lo que el PO estaba tratando de evitar, pero no elimina la necesidad de llamar a la función y luego llamar la función setInterval, por lo que guarda una línea de código. Puede detener e iniciar la función en cualquier momento por:

//Stop it 
clearTimeout(timeout); 

//Start it 
doStuff(); 
+0

plus: 'setTimeout' es preferible ya que no continuará repitiéndose si hay un error. – Hemlock

+0

+1 Creo que esta es una buena solución si no hay otra necesidad de invocar la función externamente. – user113716

+0

... aunque está perdiendo un poco de funcionalidad con su respuesta actual. OP tenía el resultado de devolución de 'setInterval' asignado a una variable, lo que puede implicar que el intervalo se debe cancelar en algún momento. Para replicar el comportamiento, debe hacer que la llamada recursiva a través de 'setTimeout' dependa del estado de un indicador que se puede configurar para detener la invocación. – user113716

Cuestiones relacionadas