简体   繁体   中英

How to get the last callback in a function with several callbacks?

I have a showMain() function with a lot of jQuery .show("slow", callback) methods, and each of these callbacks are triggered only when the corresponding slow "animation" is complete. How to write a showMain(callback) function, whose callback will be triggered only once and after all animations are complete?

Theoretically, imagine I have this set of functions

 function foo1(callback){ //do something callback(); } function foo2(callback){ //do something callback(); } function foo(callback){ foo1(callback); foo2(callback); } foo(function(){ alert("Hello"); }); 

How to write a function that will call its callback only once , and the last of them to be executed?

If I write this, the callback will be triggered twice.

how about maintaining a counter if you know how many times you are calling 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);

Note : It will work only if you know How many times you will call .show otherwise initialize the counter to 0 and increment with each show call

if you want to work with callbacks then you will need a control var. I would solve your problem doing something like:

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

Your maybe you consider using Promises and Promises.all should solve your problem too.

You could bypass the control variable issue by converting them to Promises. See this fiddle: 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'));
  }
});

Instead of console.log you can put whatever callback you like. This way you can load up an array of any size with promises, and .all will take care of executing your function when they're all finished

That's how I solved the issue:

 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')})" /> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM