2010-07-20 23 views
8

Estoy usando jQuery para configurar un temporizador o bucle de intervalo en algunos elementos para revisarlos cada dos segundos. Intenté configurar un temporizador y comprobar si debía reiniciarlo, o configurar e intervalo, y comprobar si debía detenerlo.javascript temporizador o intervalos creados en bucle utilizando el cierre

Aunque simplificado, esto es básicamente lo que necesito:

var mytimers = new Array(); 
$('div.items').each(function() { 
    myID = $(this).attr('id'); 
    mytimers[myID] = setInterval(function() { myFunction(myID) } , 3000) 
}); 
function myFunction(param) { 
    alert(param); 
    if (something()) { 
     clearInterval(mytimers[param]); 
    } 
} 

Las identificaciones para artículos de clase son id_1, ID_2, ID_3. Pero simplemente recibo 3 alertas que dan id_3. En mi código comencé tratando de pasar 'esto', pero seguí simplificándolo para resolver el problema.

¿Cómo puedo hacer para copiar la variable a una nueva dirección cada vez? Sé que necesito usar cierres. Parece estar haciendo referencia a las otras var no importa qué.

he intentado simplificarlo a un bucle con temporizadores, así:

function tester(item) { 
    return function() { 
     alert(item); 
    }; 
} 
for(x=1;x<=3;x++) { 
    setTimeout('(function() { tester(x) })(x)' , 3000); 
} 

pero creo que sólo estoy haciendo mi problema peor y eso no parece hacer nada.

He buscado las preguntas anteriores, pero la mayoría están llenas de toneladas de código adicional en lugar de reducir el problema específico y se resuelven de alguna otra manera. Me gustaría entender cómo funciona esto mejor haciendo que este ejemplo funcione. Me las arreglé, mientras escribía esto, para descubrir que puedo configurar el temporizador con una función de ayuda.

function tester(item) 
    alert(item); 
function myTimer(item) 
    setInterval(function() { tester(item); }, 3000); 
for(x=1;x<=3;x++) 
    myTimer(item); 

¿Cómo se puede hacer esto sin eso? ¿Hay alguna forma mejor?

+3

Realmente debería declarar * todas * sus variables locales con 'var', incluidos los índices de bucle. – Pointy

Respuesta

3

Estás en un cierre cuando se utiliza cada uno, sólo se ha olvidado de que su variable privada en el ámbito de la función

var mytimers = new Array(); 
$('div.items').each(function() { 
    **var** myID = $(this).attr('id'); 
    mytimers[myID] = setInterval(function() { myFunction(myID) } , 3000) 
}); 
function myFunction(param) { 
    alert(param); 
    if (something()) { 
     clearInterval(mytimers[param]); 
    } 
} 
+0

* golpea la frente * De hecho, probé var en todo tipo de lugares, excepto ese, ha. – phazei

4

han 'MyID' variable local a la función anónima, var

var myID = $(this).attr('id'); 
1

¿Desea ejecutar myFunction en cada uno de los elementos coincidentes cada tres segundos?

Prueba esto:

$('div.items').each(myFunction(this)); 

var myFunction = function(elem) { 
    return function() { 
     if (something(elem)) { 
      //return or do something with elem 
     } else { 
      window.setTimeout(myFunction(elem), 3000); 
     } 
    } 
}; 

Si se cumple la condición en la something() haya terminado, si no el propio horarios de función para ejecutar de nuevo en 3 segundos con el mismo elemento que antes. Puede llamar a esto tantas veces como desee en diferentes elementos, cada llamada tiene su propio elem.

Prefiero pasar objetos como elem y demorar el trabajo con sus internos hasta el último momento posible. Deje que something() se preocupe por la identificación o lo que sea.

Ninguna de las otras gimnasias con la matriz asociativa (en lugar de new Array() puede usar {}) o clearInterval, o las identificaciones son necesarias.

Para hacer frente a realidad su solución, como dijo Marimuthu, que dejó var de la declaración de myID, lo que significa que su mundial y se sobreescribe cada iteración.El resultado es que cuando setInterval invoca myFunction en lugar de obtener un único myID local mediante cierre, obtiene el global que ya ha sido sobrescrito umpty veces.

Cuestiones relacionadas