如何在具有多个回调的函数中获取最后一个回调



我有一个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);
}

也许您考虑使用PromisesPromises.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')})" />

最新更新