2009-08-14 3 views

Antwort

17

eine anonyme Funktion anstelle einer Zeichenfolge auf den ersten Parameter der setTimeout oder setInterval Funktionen verwenden:

// assuming that object_array is available on this scope 
setInterval(function() { foo(object_array); }, 1000); 

Warum es funktioniert:

Wenn Sie eine innere Funktion definieren, kann es verweisen zu den Variablen, die in ihrer äußeren umschließenden Funktion vorhanden sind, selbst nachdem ihre Elternfunktionen bereits beendet worden sind.

Diese Sprachfunktion heißt closures.

Wenn Sie einen String als erstes Argument dieser Funktionen übergeben, wird der Code intern mit einem Aufruf an die eval Funktion ausgeführt wird, und dies zu tun ist nicht betrachtet als good practice.

Eval bietet einen direkten Zugriff auf den JavaScript-Compiler und führt den Code mit den Rechten des Anrufers übergeben wird, auch eval wiederholt/ausgiebig (das heißt Ihre setInterval-Funktion ist ein gutes Beispiel) wird zu Performance-Problemen führen.

+0

ist es möglich, in setInterval() – coderex

+0

Ja, es ist possble und das ist der beste Weg, es – CMS

+0

@CMS zu tun: es funktioniert dank :-) – coderex

1

zuerst, dann ist es 'SetTimeout'

Sekunden, keine Zeichenfolge übergeben. Die wirkliche Lösung hängt vom Rest des Codes ab. Robusteste Art und Weise zu stoppen den Anwendungsbereich wäre:

var obj_array = something; 
function trap(obj) 
{ 
    function exec() { foo(obj); } 
    return exec; 
} 
setTimeout(trap(obj_array), 1000); 

Falle gibt eine Funktion, die das Array in ihrem Umfang gefangen hat.

var obj_array = something; 
function trap() 
{ 
    function exec() { foo(obj_array); } 
    return exec; 
} 
setTimeout(trap(), 1000); 

oder sogar:

var obj_array = something; 
function trap() 
{ 
    foo(obj_array); 
} 
setTimeout(trap, 1000); 

und schließlich kondensiert bis:

var obj_array = something; 
setTimeout(function() { foo(object_array); }, 1000); 

EDIT Dies ist eine generische Funktion, aber es spezifisch für Ihr Problem zu machen, kann es vereinfacht werden : Meine Funktionen (oder mindestens 1 Iteration von ihnen fand ich in einem Backup hier)

Function.prototype.createDelegate = function(inst, args) { 
    var me = this; 
    var delegate = function() { me.apply(inst, arguments); } 
    return args ? delegate.createAutoDelegate.apply(delegate,args) : delegate; 
}; 
Function.prototype.createAutoDelegate = function() { 
    var args = arguments; 
var me = this; 
return function() { me.apply({}, args); } 
}; 

Gegeben:

function test(a, b) { alert(a + b); } 

ANWENDUNG:

setTimeout(test.createAutoDelegate(1, 2), 1000); 

oder verschenkt:

var o = { a:1, go : function(b) { alert(b + this.a); }} 

ANWENDUNG:

setTimeout(o.go.createDelegate(o,[5]), 1000); 
//or 
setTimeout(o.go.createDelegate(o).createAutoDelegate(5), 1000); 
2

Ich bin zu expan gehen d auf Lukes Antwort hier, weil es einen Anwendungsfall adressiert, den CMS (und die meisten Antworten auf diese Art von Frage) nicht tut.

Wenn Sie Ihre Argumente für die Funktion Anruf zum Zeitpunkt der Timeout gesetzt binden müssen, eine einfache Funktion Gehäuse wird nicht funktionieren:

echo = function (txt) { console.log(txt); }; 

val = "immediate A"; 
echo(val); 

val = "delayed"; 
window.setTimeout(function() { echo(val); }, 1000); 

val = "immediate B"; 
echo(val); 

Sie Unter der Annahme, Firebug-Konsole verwenden, die oben Willen Ausgabe "sofort A", "sofort B" und dann "sofort B" 1 Sekunde später. Um den Wert zum Zeitpunkt des setTimeout-Aufrufs zu binden, verwenden Sie die Trap-Methode von Luke. Die folgende ändert es ein wenig beliebige Funktionen und Argument Längen zu akzeptieren:

echo = function (txt) { console.log(txt); }; 

trap = function (fn, args) { 
    return function() { 
     return fn.apply(this, args); 
    }; 
}; 

val = "immediate A"; 
echo(val); 

val = "delayed"; 
window.setTimeout(trap(echo, [val]), 1000); 

val = "immediate B"; 
echo(val); 

Nicht sicher, ob es ein Weg gibt den Anrufer Kontext implizit passieren, aber es könnte weiterhin einen Zusammenhang Argument, wenn „dies zu akzeptieren erweitert werden "bringt dich nicht dorthin.

+0

Ihre Version von trap die gleiche Idee zu meinem CreateDelegate und trapScope Funktionen ist. Am Ende meiner Antwort für das Interesse hinzugefügt –

+0

Ich musste dieses Problem in der Vergangenheit mehrmals und immer für peinliche Status-Tracking-Workarounds festgelegt, bis ich Ihre Lösung sah. So ziemlich jedes Thema, das ich über Timeouts und Intervalle fand, sprach über die Verwendung von Gehäusen ohne Berücksichtigung der Rennbedingungen. –

+0

'+ 1' Diese Antwort rettete meine Stirn davor, gegen eine Wand zu schlagen. Vielen Dank. – RASG