Ich habe ein Problem mit normalen ( Nicht-Ajax- ) Funktionen, die viele Animationen in jeder von ihnen beinhalten. Momentan habe ich einfach eine setTimeout
Zwischenfunktion, aber diese ist nicht perfekt, da keine Browser / Computer gleich sind.
Zusätzlicher Hinweis: Beide haben separate Animationen / etc, die kollidieren.
Ich kann nicht einfach einen in die Rückruffunktion eines anderen setzen
// multiple dom animations / etc
FunctionOne();
// What I -was- doing to wait till running the next function filled
// with animations, etc
setTimeout(function () {
FunctionTwo(); // other dom animations (some triggering on previous ones)
}, 1000);
Gibt es sowieso in js / jQuery:
// Pseudo-code
-do FunctionOne()
-when finished :: run -> FunctionTwo()
Ich weiß über $.when()
& Bescheid $.done()
, aber diese sind für AJAX ...
- MEINE AKTUALISIERTE LÖSUNG
jQuery verfügt über eine exponierte Variable (die aus irgendeinem Grund nirgendwo in den jQuery-Dokumenten aufgeführt ist) mit dem Namen $ .timers, die das Array der derzeit stattfindenden Animationen enthält.
function animationsTest (callback) {
// Test if ANY/ALL page animations are currently active
var testAnimationInterval = setInterval(function () {
if (! $.timers.length) { // any page animations finished
clearInterval(testAnimationInterval);
callback();
}
}, 25);
};
Grundlegende Verwendung:
// run some function with animations etc
functionWithAnimations();
animationsTest(function () { // <-- this will run once all the above animations are finished
// your callback (things to do after all animations are done)
runNextAnimations();
});
javascript
jquery
callback
Mark Pieszak - Trilon.io
quelle
quelle
FunctionOne
es keine Auszeit gibt oder so, können Sie einfach anrufenFunctionOne(); FunctionTwo();
, nicht wahr?$.when
und$.done
sind nicht unbedingt nur für Ajax. Wenn Sie verschiedene asynchrone Aufgaben in FunctionOne haben, die Sie beenden möchten, bevor Sie FunctionTwo starten, können SieDeferred
Objekte erstellen , sie in ein Arrayresolve()
$.when.apply($, array).then(function(){...});
isRunning
Flagge hinzuzufügen .Antworten:
Sie können jQuery's verwenden
$.Deferred
var FunctionOne = function () { // create a deferred object var r = $.Deferred(); // do whatever you want (e.g. ajax/animations other asyc tasks) setTimeout(function () { // and call `resolve` on the deferred object, once you're done r.resolve(); }, 2500); // return the deferred object return r; }; // define FunctionTwo as needed var FunctionTwo = function () { console.log('FunctionTwo'); }; // call FunctionOne and use the `done` method // with `FunctionTwo` as it's parameter FunctionOne().done(FunctionTwo);
Sie können auch mehrere Verzögerungen zusammenpacken:
var FunctionOne = function () { var a = $.Deferred(), b = $.Deferred(); // some fake asyc task setTimeout(function () { console.log('a done'); a.resolve(); }, Math.random() * 4000); // some other fake asyc task setTimeout(function () { console.log('b done'); b.resolve(); }, Math.random() * 4000); return $.Deferred(function (def) { $.when(a, b).done(function () { def.resolve(); }); }); };
http://jsfiddle.net/p22dK/
quelle
.promise()
animate
? Denn sonst sehe ich hier nicht wirklich die Notwendigkeit des Versprechensobjekts.Deferred.promise
, sondern die jQuery-Methode api.jquery.com/promiseFügen Sie am Ende der ersten Funktion Folgendes hinzu
return $.Deferred().resolve();
Rufen Sie beide Funktionen so auf
quelle
Zusammen mit Yoshis Antwort habe ich eine weitere sehr einfache Lösung (Rückruftyp) für Animationen gefunden.
jQuery verfügt über eine exponierte Variable (die aus irgendeinem Grund nirgendwo in den jQuery-Dokumenten aufgeführt ist) mit dem Namen $ .timers , die das Array der derzeit stattfindenden Animationen enthält.
function animationsTest (callback) { // Test if ANY/ALL page animations are currently active var testAnimationInterval = setInterval(function () { if (! $.timers.length) { // any page animations finished clearInterval(testAnimationInterval); callback(); } }, 25); };
Grundlegende Verwendung:
functionOne(); // one with animations animationsTest(functionTwo);
Hoffe das hilft einigen Leuten!
quelle
Ist es das, was du meinst, Mann: http://jsfiddle.net/LF75a/
Sie haben eine Funktion, die die nächste Funktion auslöst und so weiter, dh fügen Sie einen weiteren Funktionsaufruf hinzu und fügen Sie dann Ihren
functionONe
am unteren Rand hinzu.Bitte lassen Sie mich wissen, wenn ich etwas verpasst habe, hoffe es passt zur Sache
:)
oder dies: Rufen Sie eine Funktion auf, nachdem die vorherige Funktion abgeschlossen wurde
Code:
function hulk() { // do some stuff... } function simpsons() { // do some stuff... hulk(); } function thor() { // do some stuff... simpsons(); }
quelle
Diese Antwort verwendet
promises
eine JavaScript-Funktion desECMAScript 6
Standards. Wenn Ihre Zielplattform dies nicht unterstütztpromises
, füllen Sie sie mit PromiseJs .Sie können das
Deferred
Objekt, das jQuery für die Animation erstellt, mithilfe.promise()
des Animationsaufrufs abrufen. Das Einwickeln dieserDeferreds
in ES6Promises
führt zu einem viel saubereren Code als die Verwendung von Timern.Sie können auch
Deferreds
direkt verwenden, dies wird jedoch generell nicht empfohlen, da sie nicht der Promises / A + -Spezifikation entsprechen.Der resultierende Code würde folgendermaßen aussehen:
var p1 = Promise.resolve($('#Content').animate({ opacity: 0.5 }, { duration: 500, queue: false }).promise()); var p2 = Promise.resolve($('#Content').animate({ marginLeft: "-100px" }, { duration: 2000, queue: false }).promise()); Promise.all([p1, p2]).then(function () { return $('#Content').animate({ width: 0 }, { duration: 500, queue: false }).promise(); });
Beachten Sie, dass die Funktion in
Promise.all()
das Versprechen zurückgibt. Hier geschieht Magie. Wenn in einemthen
Anruf ein Versprechen zurückgegebenthen
wird, wartet der nächste Anruf darauf, dass dieses Versprechen gelöst wird, bevor er ausgeführt wird.jQuery verwendet für jedes Element eine Animationswarteschlange. Animationen auf demselben Element werden also synchron ausgeführt. In diesem Fall müssten Sie überhaupt keine Versprechen verwenden!
Ich habe die jQuery-Animationswarteschlange deaktiviert, um zu demonstrieren, wie es mit Versprechungen funktionieren würde.
Promise.all()
nimmt eine Reihe von Versprechungen und schafft eine neuePromise
, die beendet wird, nachdem alle Versprechungen in der Reihe beendet wurden.Promise.race()
nimmt auch eine Reihe von Versprechungen, endet aber, sobald die erstePromise
fertig ist.quelle
ECMAScript 6 UPDATE
Dies verwendet eine neue JavaScript-Funktion namens Promises
functionOne (). then (functionTwo);
quelle
Sie können dies über die Rückruffunktion tun.
$('a.button').click(function(){ if (condition == 'true'){ function1(someVariable, function() { function2(someOtherVariable); }); } else { doThis(someVariable); } });
Funktion function1 (param, callback) {... do stuff callback (); }}
quelle
Hier ist eine Lösung für n-Aufrufe (rekursive Funktion). https://jsfiddle.net/mathew11/5f3mu0f4/7/
function myFunction(array){ var r = $.Deferred(); if(array.length == 0){ r.resolve(); return r; } var element = array.shift(); // async task timer = setTimeout(function(){ $("a").text($("a").text()+ " " + element); var resolving = function(){ r.resolve(); } myFunction(array).done(resolving); }, 500); return r; } //Starting the function var myArray = ["Hi", "that's", "just", "a", "test"]; var alerting = function (){window.alert("finished!")}; myFunction(myArray).done(alerting);
quelle
Sie können das Javascript verwenden
Promise
undasync/await
einen synchronisierten Aufruf der Funktionen implementieren.Angenommen, Sie möchten eine
n
Reihe von Funktionen synchron ausführen , die in einem Array gespeichert sind. Hier ist meine Lösung dafür.async function executeActionQueue(funArray) { var length = funArray.length; for(var i = 0; i < length; i++) { await executeFun(funArray[i]); } }; function executeFun(fun) { return new Promise((resolve, reject) => { // Execute required function here fun() .then((data) => { // do required with data resolve(true); }) .catch((error) => { // handle error resolve(true); }); }) }; executeActionQueue(funArray);
quelle