5

Me he encontrado con un problema donde mi aplicación vive en un iframe y se está llamando desde un dominio externo. IE9 no activará el evento de carga cuando el iframe se carga correctamente, así que creo que estoy atascado usando setTimeout para sondear la página.Pasar parámetros a un cierre para setTimeout

De todos modos, quiero ver qué duración generalmente se necesita para completar mi setTimeout, así que quería poder registrar la demora que dispara el setTimeout de mi devolución de llamada, pero no estoy seguro de cómo pasar ese contexto a para que pueda iniciar sesión.

App.readyIE9 = function() { 
    var timings = [1,250,500,750,1000,1500,2000,3000];  
    for(var i = 0; i < timings.length; i++) { 
    var func = function() { 
    if(App.ready_loaded) return; 
     console.log(timings[i]); 
     App.readyCallBack(); 
    }; 
    setTimeout(func,timings[i]); 
    } 
}; 

Sigo recibiendo LOG: indefinido en la consola de IE9.

¿Cuál es el método adecuado para lograr esto?

Gracias

+0

esto podría ser una pregunta mucho mejor si lo haces más genérico, como la eliminación de tantos valores de 'timing' y todas las líneas con 'App'! – cregox

Respuesta

10

Esto está sucediendo porque no está cerrando alrededor del valor de i en su func. Cuando se completa el ciclo, i es 8 (timings.length), que no existe en la matriz.

que tiene que hacer algo como esto:

App.readyIE9 = function() { 
    var timings = [1,250,500,750,1000,1500,2000,3000];  
    for(var i = 0; i < timings.length; i++) { 
    var func = function(x) { 
     return function(){ 
      if(App.ready_loaded) return; 
      console.log(timings[x]); 
      App.readyCallBack(); 
     }; 
    }; 
    setTimeout(func(i),timings[i]); 
    } 
}; 
+0

+1 para la solución inicialmente correcta. – VisioN

+0

Gracias, esto es exactamente lo que estaba buscando. – user126715

+0

@ user321521: De nada :) –

10

Cuando su función es llamado por setTimeout en algún momento en el futuro, el valor de i Ya se ha incrementado hasta el final de su rango por el for bucle para console.log(timings[i]); informes undefined.

Para usar i en esa función, debe capturarlo en un cierre de función. Hay varias maneras de hacer eso. Se recomienda usar una función de aplicación directa para capturar el valor de i así:

App.readyIE9 = function() { 
    var timings = [1,250,500,750,1000,1500,2000,3000];  
    for(var i = 0; i < timings.length; i++) { 
    (function(index) { 
     setTimeout(function() { 
      if(App.ready_loaded) return; 
      console.log(timings[index]); 
      App.readyCallBack(); 
     }, timings[index]); 
    })(i); 
    } 
}; 

como un poco de explicación para que esto funciona: i se pasa a la función de aplicación directa como primer argumento a ese función. Ese primer argumento se llama index y se congela con cada invocación de la función de autoejecución, por lo que el bucle for no hará que cambie antes de que se ejecute la devolución de llamada setTimeout. Por lo tanto, al hacer referencia a index dentro de la función autoejecutable obtendrá el valor correcto del índice de matriz para cada devolución de llamada setTimeout.

3

Este es un problema habitual cuando se trabaja con setTimeout o setInterval devoluciones de llamada. Usted debe pasar el valor i a la función:

var timings = [1, 250, 500, 750, 1000, 1500, 2000, 3000], 
    func = function(i) { 
     return function() { 
      console.log(timings[i]); 
     }; 
    }; 

for (var i = 0, len = timings.length; i < len; i++) { 
    setTimeout(func(i), timings[i]); 
} 

DEMO:http://jsfiddle.net/r56wu8es/

+0

Esto llamará 'func' con' i' como parámetro, y pasará su valor de retorno a 'setTimeout'. 'func' necesita devolver una función. –

+0

@Rocket. Derecha. Gracias, corregido. – VisioN

+0

No lo solucionaste. 'func' todavía devuelve' undefined'. –

Cuestiones relacionadas