2012-04-16 13 views
46

Tengo este contador que hice pero quiero que funcione para siempre, es realmente simple, ¿qué estoy haciendo mal aquí?setInterval callback only runs once

function timer() { 
    console.log("timer!") 
} 

window.setInterval(timer(), 1000) 
+6

El problema es 'timer()' invoca el objeto-función que resultó de evaluar 'timer' y luego pasa el resultado (' undefined') a 'setTimeout'. Entonces, no lo invoques. En su lugar, simplemente pase el objeto-función: 'setInterval (timer, 1000)' –

Respuesta

76

Ha utilizado una llamada de función en lugar de una referencia de función como el primer parámetro de setInterval. Hacerlo de esta manera:

function timer() { 
    console.log("timer!"); 
} 

window.setInterval(timer, 1000); 

o más corto (pero cuando la función se hace más grande también menos legible):

window.setInterval(function() { 
    console.log("timer!"); 
}, 1000) 
+1

la respuesta señala correctamente que la función de devolución de llamada no debe tener el "()" en el argumento. – Kristian

+2

Según https://developer.mozilla.org/en/Extensions/Common_causes_of_memory_leaks_in_extensions#Be_careful_with_setInterval.2FsetTimeout, la versión más corta puede causar pérdida de memoria. –

+0

según el enlace de Crend King, mozilla apesta. – nothrow

8

setInterval y setTimeoutdebe usarse con devoluciones de llamada, como:

setInterval(timer, 1000); 

o funciones sin nombre:

setInterval(function() { console.log("timer!"); }, 1000); 

Por qué su código no funciona: cuando pasa una función como argumento a otra función con corchetes, p. doSomething (someFunc()) está pasando el resultado de la función.

Cuando la función se pasa como objeto, p. doSomething (someFunc) está pasando una devolución de llamada. De esta forma, someFunc se pasa como referencia y se ejecuta en algún lugar de la función de llamada. Esto es lo mismo que los punteros a funciones en otros idiomas.

Un error común es usar estas dos funciones como se muestra en w3schools. Esto hace una llamada implícita al eval.