等到有animation的函数结束后再运行另一个函数

我遇到了一个正常( 非Ajax )函数的问题,每个函数都涉及大量的animation 。 目前我只是有一个setTimeoutfunction之间,但这并不完美,因为没有浏览器/电脑是相同的。

附加说明:他们都有单独的animation/等相撞。

我不能简单地把一个放在另一个的callback函数中

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

反正在js / jQuery中有:

 // Pseudo-code -do FunctionOne() -when finished :: run -> FunctionTwo() 

我知道$.when()$.done() ,但这些是为AJAX …


  • 我更新的解决scheme

jQuery有一个暴露的variables(出于某种原因,没有在jQuery文档中的任何地方列出),名为$ .timers,其中包含当前正在发生的animation数组。

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

基本用途:

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

你可以使用jQuery的$.Deferred

 var FunctionOne = function () { // create a deferred object var r = $.Deferred(); // do whatever you want (eg 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); 

你也可以打包多个延期:

 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/

将以下内容添加到第一个函数的末尾

 return $.Deferred().resolve(); 

调用这样的function

 functionOne().done(functionTwo); 

随着Yoshi的回答,我发现了另一个非常简单的(callbacktypes)animation解决scheme。

jQuery有一个暴露的variables(出于某种原因,没有在jQuery文档中的任何地方列出),名为$ .timers ,其中包含当前正在发生的animation数组。

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

基本用途:

 functionOne(); // one with animations animationsTest(functionTwo); 

希望这可以帮助一些人!

这是你的意思吗: http : //jsfiddle.net/LF75a/

你将有一个函数触发下一个函数等,即添加另一个函数调用,然后添加你的functionONe在它的底部。

请让我知道如果我错过了什么,希望它适合原因:)

或者 : 在前一个function完成后调用一个函数

码:

 function hulk() { // do some stuff... } function simpsons() { // do some stuff... hulk(); } function thor() { // do some stuff... simpsons(); } 

这个答案使用了ECMAScript 6标准的JavaScript特性promises 。 如果您的目标平台不支持promises ,请使用PromiseJs进行填充 。

您可以使用jQuery在animation调用中使用.promise()创build的Deferred对象。 将这些Deferreds包装到ES6 Promise中会比使用定时器产生更清晰的代码。

您也可以直接使用Deferreds ,但是由于它们不遵循Promise / A +规范,所以通常不鼓励。

结果代码如下所示:

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

请注意, Promise.all()中的函数返回promise。 这是魔术发生的地方。 如果在一次调用中返回一个承诺,那么下一次调用将等待该承诺在执行之前被解决。

jQuery为每个元素使用一个animation队列。 所以同一元素上的animation是同步执行的。 在这种情况下,你根本不必使用promise。

我禁用了jQueryanimation队列来演示如何使用promise。

Promise.all()接受一组promise,并创build一个新的Promise ,完成数组中的所有promise。

Promise.race()也承诺了一系列的承诺,但是当第一个Promise完成时,就结束了。

ECMAScript 6 UPDATE

这使用了一个名为Promises的JavaScript新特性

functionOne(),然后(functionTwo)。

你可以通过callback函数来完成。

 $('a.button').click(function(){ if (condition == 'true'){ function1(someVariable, function() { function2(someOtherVariable); }); } else { doThis(someVariable); } }); 

函数function1(param,callback){… do stuff callback(); }

这是一个解决n个调用(recursion函数)。 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);