2009-03-25 12 views
9

Grundsätzlich möchte ich in der Lage sein, jeden Befehl in eine $ .holdTillFinished() -Methode einzuschließen, die es nicht erlaubt, dass die Ausführung fortgesetzt wird, bis die angegebene Methode/jquery-Animation fertig ist.Ist es möglich, die Ausführung in Javascript/Jquery zu stoppen?

Ich vermute, dass dies in Javascript schwierig oder sogar unmöglich sein kann, aber ich hoffe, dass jemand es wissen wird.

Ich möchte nicht darüber hören, wie ich einen Callback in eine Animation weitergeben kann, um sie auf Vollständigkeit auszuführen, oder irgendetwas ähnliches.

Ich möchte wirklich wissen, ob so etwas möglich ist und wie es geht.

Wenn das nicht passieren wird, wenn jemand ein nettes Warteschlangen-Plugin kennt, das in der Lage ist, sowohl benutzerdefinierte Methoden als auch Animationen in die Warteschlange zu stellen, wäre das auch cool. Was ich wirklich will, ist ein Weg, obwohl die Ausführung zu verzögern. (Und ermöglicht gleichzeitig Animationen funktionieren)

+0

@thirsty: Sie wollen Warteschlange und entmutigen, denke ich (bereits vorgeschlagen und von Ihnen unten entlassen). Sie können beliebige Methoden zusammen mit Animationen in die Warteschlange stellen und sie werden in der richtigen Reihenfolge ausgeführt. Wenn dies nicht das ist, was Sie fragen, können Sie dann Ihre Frage mit einem Beispiel klären, was Sie zu tun versuchen? – Prestaul

+0

Ich habe keine Warteschlange gesehen, die für Funktionen funktioniert. Was ich meine ist, wenn ich eine Animation, dann eine Funktion, dann eine Animation in die Warteschlange übergeben, während diese Animationen abgespielt werden, sollte die Funktion nicht ausgeführt werden. Ich möchte auch nicht angeben müssen, wie lange die Ausführung der Funktion dauern wird. – thirsty93

+0

Aber wirklich was ich will, ist ein Wrapper, der alle Javascript stoppt, bis die Funktion/Animation, die ich in es passiert habe, – thirsty93

Antwort

10

ich vermute, dass dies schwierig sein kann, oder sogar unmöglich in Javascript

Ihr Verdacht ist richtig. Methoden wie Animationen, Benutzereingabeschleifen und 'async = true' XMLHttpRequests müssen die Kontrolle an den Browser zurückgeben, um fortzufahren, und der Browser kann die Kontrolle nicht zurückbekommen, bis jede Verschachtelungsebene des Funktionsaufrufs zurückgekehrt ist. Das bedeutet, dass Ihr gesamter Code einschließlich der Funktion, die 'holdTillFinished()' heißt, sich auflösen müsste: 'holdTillFinished()' ist daher unmöglich.

Andere Sprachen verfügen über Flusssteuerungsfunktionen, mit denen Sie einen asynchronen Prozess effektiv ausführen können, der dem Aufrufer als synchron erscheint und umgekehrt. Die bekanntesten sind threads und continuations. JavaScript verfügt nicht über diese Funktionen. Aus diesem Grund sollten Sie Timeouts und Rückrufe am besten vermeiden.

(Wenn Sie einen Callback als Inline-Funktion definieren, um auf die Variablen der umschließenden Funktion in einer Closure zuzugreifen, müssen Sie sich zumindest etwas Mühe machen; einige andere Sprachen müssen jedes umschließende Glied in einem Objekt umbrechen Eigenschaften, um dies zu erreichen.)

+0

Was sind diese anderen Sprachen? Neugierig ... –

+0

Nun, so ziemlich alle modernen (Nicht-Browser-) Sprachen geben Ihnen Threads, die OS-Unterstützung verwenden. Continuations/Korotinen können in mindestens Haskell, ML und Scheme und einigen Erweiterungen zu anderen Sprachen (zB Stackless Python) gefunden werden; Es gibt Grundelemente in C, die zum Aufbau von Fortsetzungen verwendet werden können. – bobince

+0

Natürlich stecken Sie in der Browser-Welt fest: abgesehen von JavaScript gibt es nur VBScript, und das ist noch schlimmer! JavaScript 1.7 (in Firefox 2) gibt Ihnen Generatoren im Python-Stil, die eine eingeschränkte Form der Fortsetzung sind, die Ihnen hier nicht wirklich helfen würden. – bobince

3

Sie sind wahrscheinlich der Suche nach http://docs.jquery.com/Effects/queue

Aber wenn Sie für eine allgemeinere Art und Weise gesuchte Dinge zu verzögern, ich habe diesen Schnipsel verwendet vor (ich habe es nicht schreiben, so dass alle Kredite an den ursprünglichen Autor geht):

//Simple wrapper enabling setTimout within chained functions. 
$.fn.wait = function(time, type) { 
    time = time || 1000; 
    type = type || "fx"; 
    return this.queue(type, function() { 
    var self = this; 
    setTimeout(function() { 
     $(self).dequeue(); 
    }, time); 
    }); 
}; 
+0

gelöst hat Dies verzögert die Ausführung nicht, bis die Funktion endet. Das verzögert die Ausführung in der Warteschlange um ein bestimmtes Zeitlimit, das ich einstelle. Ich weiß nicht, wie lange es dauert, eine bestimmte Funktion auszuführen, und ich sollte nicht raten müssen. – thirsty93

+0

Das ist aber besser als nichts. Aber es ist wirklich nicht das, wonach ich suche. – thirsty93

0

Sie könnten eine Publish/Subscribe-Architektur verwenden, um zu erreichen, was Sie wollen. Ohne viel darüber zu wissen, was genau Sie erreichen wollen, ist es wahrscheinlich, dass es für Sie funktioniert.

Die Funktionsweise ist, dass Sie die Fertigstellung der Funktion als ein Ereignis betrachten, das Sie anhören und an Handler anhängen können. Dojo has a pubsub mechanism, obwohl ich sicher bin, dass es andere gibt.

+0

Genau das möchte ich nicht. Ein Callback, den ich an die betreffende Funktion/Animation weitergebe – thirsty93

0

Es verteidigt Situation, aber normalerweise ist es notwendig, ein Verarbeitungsbild zu zeigen, wenn AJAX aufgerufen wird oder eine Schleife in Javascript ausgeführt wird. Ich habe eine Situation, in der ich AJAX in einer Schleife anrufe, für den Benutzer, der das verarbeitende Bild zeigt, wird gezeigt. Zum Beenden habe ich einen Trick gemacht. Ich habe eine Schaltfläche gesetzt, um den Job abzubrechen, wenn diese Funktion aufgerufen wird. Ich setze eine globale Variable, sage 'cancelJob' auf 'true' und in der Schleife, wo ich diese globale Variable überprüfe, wenn dies der Fall ist, gibt run return false zurück.

var cancelJob = false; 
foreach(){ 
    if(cancelJob == true) 
     return false; 
} 

function cancelButtonPress(){ 
    cancelJob = true; 
}