我遇到了普通(非ajax )函数的问题,这些函数在每个函数中都包含大量动画。目前我只是在函数之间有setTimeout
,但这并不完美,因为没有浏览器/计算机是相同的。
附加说明:它们都有单独的动画/等碰撞。
我不能简单地将一个放在另一个
的回调函数中// 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 ......
jQuery有一个名为$ .timers的公开变量(由于某些原因未在jQuery文档中的任何位置列出),它包含当前正在进行的动画数组。
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();
});
答案 0 :(得分:109)
您可以使用jQuery的$.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);
您还可以将多个延迟包装在一起:
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();
});
});
};
答案 1 :(得分:13)
将以下内容添加到第一个函数的末尾
return $.Deferred().resolve();
调用这两个函数
functionOne().done(functionTwo);
答案 2 :(得分:2)
在Yoshi的回答中,我找到了另一个非常简单的(回调类型)动画解决方案。
jQuery有一个名为 $。timers 的公开变量(由于某些原因未在jQuery文档中列出),它包含当前正在进行的动画数组。
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);
希望这可以帮助一些人!
答案 3 :(得分:1)
这就是你的意思:http://jsfiddle.net/LF75a/
您将有一个函数触发下一个函数,依此类推,即添加另一个函数调用,然后在其底部添加functionONe
。
请知道我是否遗漏了什么,希望它符合原因:)
或:Call a function after previous function is complete
<强>代码:强>
function hulk()
{
// do some stuff...
}
function simpsons()
{
// do some stuff...
hulk();
}
function thor()
{
// do some stuff...
simpsons();
}
答案 4 :(得分:1)
promises
,ECMAScript 6
标准的JavaScript功能。如果您的目标平台不支持promises
,请将其填充为PromiseJs。您可以在动画调用中使用Deferred
获取jQuery为动画创建的.promise()
对象。将这些Deferreds
包装到ES6 Promises
会产生比使用计时器更清晰的代码。
您也可以直接使用Deferreds
,但通常不鼓励这样做,因为它们不遵循Promises / 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()
中的函数会返回承诺。这就是魔术发生的地方。如果在then
调用中返回了一个promise,则下一个then
调用将等待该promise在执行之前被解析。
jQuery为每个元素使用动画队列。因此,同一元素上的动画是同步执行的。在这种情况下,你根本不必使用承诺!
我已经禁用了jQuery动画队列,以演示它如何与promises一起使用。
Promise.all()
获取一系列promise,并创建一个新的Promise
,在数组中的所有promise完成后完成。
Promise.race()
也会接受一系列承诺,但会在第一个Promise
完成后立即结束。
答案 5 :(得分:1)
ECMAScript 6更新
这使用了一个名为Promises的新功能
functionOne(),然后(functionTwo);
答案 6 :(得分:0)
您可以通过回调功能来完成。
$('a.button').click(function(){
if (condition == 'true'){
function1(someVariable, function() {
function2(someOtherVariable);
});
}
else {
doThis(someVariable);
}
});
function function1(param,callback){ ...做东西 打回来(); }
答案 7 :(得分:0)
这是n调用的解决方案(递归函数)。 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);
答案 8 :(得分:0)
您可以使用JavaScript Promise
和async/await
来实现函数的同步调用。
假设您要以同步方式执行存储在数组中的n
个函数,这是我的解决方案。
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);