我有一个showMain()
函数,里面有很多jQuery.show("slow", callback)
方法,这些回调中的每一个只有在相应的慢速"动画"完成时才会触发。如何编写一个showMain(callback)
函数,其回调只会触发一次,并且在所有动画完成后?
从理论上讲,假设我有这组函数
function foo1(callback){
//do something
callback();
}
function foo2(callback){
//do something
callback();
}
function foo(callback){
foo1(callback);
foo2(callback);
}
foo(function(){
alert("Hello");
});
如何编写一个只调用一次回调,最后一个执行的函数?
如果我写这个,回调将被触发两次。
如果你知道你叫了多少次节目,那么维护一个计数器怎么样,
var callback = function() {....} // the function you want to execute when all done
var itemsToShow = 4; // just an example
var slowCallback = function(){
itemsToShow--;
if(itemsToShow===0) {
callback();
}
};
$(...).show('slow', slowCallback);
$(...).show('slow', slowCallback);
$(...).show('slow', slowCallback);
$(...).show('slow', slowCallback);
注意:只有当您知道将调用多少次.show
否则初始化计数器以0
并随着每次show
调用而递增时,它才有效
如果你想使用回调,那么你需要一个控制变量。我会通过以下操作解决您的问题:
var i = 2 // number of your "shows" methods.
function foo1(callback){
//do something
x = x-1;
if(x<=0)callback();
}
function foo2(callback){
//do something
x = x-1;
if(x<=0)callback();
}
function foo(callback){
foo1(callback);
foo2(callback);
}
也许您考虑使用Promises
,Promises.all
也应该可以解决您的问题。
您可以通过将它们转换为 Promise 来绕过控制变量问题。看到这个小提琴:https://jsfiddle.net/kqso0kkb/1/
$(document).ready(function() {
console.clear();
Promise.all([one(), two()]).then(() => {
console.log('all done');
})
function one() {
return new Promise((resolve, reject) => {
$('#div').show("slow", resolve);
}).then(() => console.log('done 1'));
}
function two() {
return new Promise((resolve, reject) => {
$('#div').show("slow", resolve);
}).then(() => console.log('done 2'));
}
});
而不是console.log
您可以放置任何您喜欢的回调。通过这种方式,您可以使用 promise 加载任何大小的数组,.all 将在它们全部完成后负责执行您的函数
这就是我解决问题的方式:
function foo(callback){
$("#div1").show("slow");
$("#div2").show("fast");
if (typeof callback === 'function'){
$("#div1, #div2").promise().done(callback);
}
}
#div1, #div2{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1">
Text1
</div>
<div id="div2">
Text2
</div>
<input type="button" value="show" onClick="foo(function(){alert('Show Once')})" />