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

时间:2017-07-14 20:59:06

标签: javascript jquery callback

我有一个带有大量jQuery .show("slow", callback)方法的showMain()函数,并且只有在相应的慢“动画”完成时才触发每个回调。如何编写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");
});

如何编写一个只调用一次的回调函数,然后执行 last 的函数?

如果我写这个,回调将被触发两次。

4 个答案:

答案 0 :(得分:1)

如果你知道多少次调用show,那么如何维护一个计数器,

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来电增加

答案 1 :(得分:1)

如果你想使用回调,那么你需要一个控制变量。我会解决你的问题,例如:

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来解决您的问题。

答案 2 :(得分:1)

您可以通过将控制变量转换为Promises来绕过控制变量问题。看到这个小提琴: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你可以放任何你喜欢的回调。通过这种方式,您可以使用promises加载任意大小的数组,并且.all将在完成所有功能后执行您的功能

答案 3 :(得分:1)

我是如何解决这个问题的:

&#13;
&#13;
function foo(callback){
  
  $("#div1").show("slow");
  $("#div2").show("fast");
  
  if (typeof callback === 'function'){
    $("#div1, #div2").promise().done(callback);
  }
}
&#13;
#div1, #div2{
  display:none;
}
&#13;
<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')})" />
&#13;
&#13;
&#13;