5

Ich habe ein Problem, wo meine App lebt in einem Iframe und es wird von einer externen Domäne aufgerufen. IE9 wird das load-Ereignis nicht auslösen, wenn der iframe korrekt geladen wird. Ich denke, dass ich mit setTimeout festhalte, um die Seite abzufragen.Parameter in eine Schließung für setTimeout übergeben

Wie auch immer, ich möchte sehen, welche Dauer in der Regel benötigt wird, um meine setTimeout abzuschließen, also wollte ich in der Lage sein, die Verzögerung der setTimeout von meinem Rückruf zu protokollieren, aber ich bin mir nicht sicher, wie diesen Kontext übergeben damit ich es protokollieren kann.

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]); 
    } 
}; 

Ich bekomme immer LOG: undefiniert in IE9 Konsole.

Was ist die richtige Methode, um dies zu erreichen?

Dank

+0

dies eine so viel bessere Frage sein könnte, wenn Sie es allgemeinere machen, wie so viele Werte von 'timing' Entfernen und alle Zeilen mit 'App'! – cregox

Antwort

10

Dies passiert, weil Sie den Wert i in Ihrem func nicht schließen. Wenn die Schleife beendet ist, ist i 8 (timings.length), die nicht im Array vorhanden ist.

Sie brauchen so etwas wie dies zu tun:

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 für die anfänglich korrekte Lösung. – VisioN

+0

Danke, das ist genau das, was ich gesucht habe. – user126715

+0

@ user321521: Gern geschehen :) –

10

Wenn Ihre Funktion von setTimeout irgendwann in der Zukunft genannt wird, hat sich der Wert von i bereits bis Ende das Sortiment durch die for Schleife so console.log(timings[i]); Berichte undefined erhöht worden.

Um i in dieser Funktion zu verwenden, müssen Sie es in einem Funktionsabschluss erfassen. Dafür gibt es mehrere Möglichkeiten. Ich würde vorschlagen, eine selbstausführende Funktion mit dem Wert von i wie folgt zu erfassen:

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); 
    } 
}; 

Als wenig Erklärung für die dies funktioniert: i zu, dass auf die selbstausführende Funktion als erstes Argument übergeben wird Funktion. Dieses erste Argument heißt index und wird bei jedem Aufruf der selbstausführenden Funktion eingefroren, so dass die Schleife for keine Änderung verursacht, bevor der Rückruf setTimeout ausgeführt wird. Wenn Sie auf index innerhalb der selbstausführenden Funktion verweisen, wird der korrekte Wert des Array-Index für jeden setTimeout Callback abgerufen.

3

Dies ist ein übliches Problem ist, wenn Sie mit setTimeout oder setInterval Rückrufen arbeiten. Sie sollen den i Wert an die Funktion übergeben:

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

Dies wird 'func' mit' i' als Parameter aufrufen und den Rückgabewert an 'setTimeout' übergeben. 'func' muss eine Funktion zurückgeben. –

+0

@Rocket. Recht. Danke, korrigiert. – VisioN

+0

Sie haben es nicht behoben. 'func' gibt immer noch' undefined' zurück. –

Verwandte Themen