4

is there a way to call a custom function after another completes. Lots of jquery includes a way to do a call back, like when an animation completes you can just give it another function as a last parameter. But is there anyway to string together function1(params, function1(){alert('2');}) or something? I honestly have no idea how it would look.

Thank you

2
  • 1
    You might also want to do some research on promises and AOP, as overuse of callbacks leads to ugly code. Commented Nov 16, 2012 at 17:17
  • btw there's a lot of "function1" in your question... Commented Nov 16, 2012 at 17:31

5 Answers 5

5

You can create a function pointer with something like:

var yourCallback = function() {
    alert('2');
}

You can think of it as an object containing the function itself (not its return value). Since it is an object, you can pass it around to other functions.

Then pass that to the function you are calling as an argument (do not invoke it with (), as that would pass its return value):

function1(params, yourCallback);

Finally, in function1, invoke your callback when you need it:

function function1(args, callback) {
    //Some code
    if (callback) {
        callback();
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

I am trying wrap my head around this answer, and make a working fiddle. Would it be too much to ask for you to make one though, so that I can see it in action. Thank you so much.
@thomas I've also updated my post with (hopefully helpful) information.
thanks! this is actually more understandable than I thought it might be. If I wanted to add a third function to be called last, so I could do alerts of 1, 2, and 3, would I then var yourCallback = function(secondCallback)? Of course I'm trying it on my own, just a lot to juggle mentally..
@thomas, actually by passing that argument, you would be invoking the function, and thus passing its return value. So you'd need to pass the arguments and the callback functions as separate params. Does that make sense? It's a little tricky when you first see it. Another thing you could do is wrap the callback (with the parameter) in an anonymous function, such as: function() { var yourCallback = function(secondCallback); } so that the value returned IS your function.
yes, thank you for the additional information. my fiddle is not working with the three however. do you mind taking a look. jsfiddle.net/loren_hibbard/WfKx2/1
|
0
function doSomething(arg1, callback){
    // bla bla bla
    callback();
}

1 Comment

and callback() can be declared elsewhere on the page?
0

You'd structure your function something like this:

function one(x, y, z, callback) {
   // do operations here

   callback();
}

Then, since functions are objects you could pass in a function through the callback parameter, IE:

one(1, 2, 3, function(){alert('hello');});

Or

var func = function() { alert('hello'); };
one(1, 2, 3, func);

Or

function func() {
  alert('hello');
}

one(1, 2, 3, func);

Comments

0

While callbacks are convenient, overuse can lead to ugly and unmaintainable code. Besides standard callbacks shown in other answers, you might want to look at other patterns like deferred/promises and AOP.

In jQuery, promises are implemented with when() and then().

requirejs is also a good startpoint.

2 Comments

can you show me an example of how this callback functionality can be implemented with when() and then(). I have tried to read about them before and thought they were used mainly for complicated ajax stuff. Also, i remember they, themselves, being quite complicated heheh
@thomas correct, and you'll certainly rely on a library to implement promises. They work for any asynchronous action, not just ajax (if your functions are not asynchronous, then you don't need a callback). Definitely worth considering if in practice you need to chain multiple callbacks.
0

Technically the pattern you're asking for is:

function myFunctionNeedsACallback(param1, callback) {
    //do stuff with param1
    if(typeof callback === "function"){
        callback.call(yourThisParam, anyOtherParams);
    }
}

While this is a useful pattern... overuse will lead to ugly, untestable, and unmaintainable code. Use with discretion.

Your example would work just fine:

myFunctionNeedsACallback(param, function() { alert('2'); });

//will alert 2 after running the rest of the contents of the function

EDIT

To address thomas's situation:

function ajaxCall1(){
    return $.ajax(/*your parameters NO SUCCESS CALLBACK NEEDED*/);
}

function ajaxCall2(){
    return $.ajax(/*your parameters NO SUCCESS CALLBACK NEEDED*/);
}

function ajaxCall3(){
    return $.ajax(/*your parameters NO SUCCESS CALLBACK NEEDED*/);
}

$.when(ajaxCall1(), ajaxCall2(), ajaxCall3()).then(function(results1, results2, results3) {
    //do stuff with all 3 results without "nesting" things
});

8 Comments

What not-ugly alternative do you recommend then for such a problem? I can only think of events, which would lead to even more complicated code. I personally think it's a very elegant solution, especially if you're already using jquery which is full of this pattern.
@Andy: Overuse will lead to ugly code. Callbacks in and of themselves are not a problem. It'd be horrible to not have them. However, I see people doing stuff like (psuedo) ajax(ajax(ajax(/*do something with all 3 results */))) and it just hurts. As Christophe said in the comments on the question, Promises make that kind of code much easier to work with..and read
@BLSully the functions I'm calling do use ajax. three calls actually. What you're talking about in the psuedo you wrote is sorta what I'm trying to avoid. Each subsequent call happening in the success callback of the ajax function. Do you have a tutorial that shows how I can use promises to fire off 3 or 4 functions using it? Thank you very much
This is getting clearer. I'd like to keep my success functions just because I have a json template in each one and it makes it easier for me if the ajax calls are together with the functionality that does something with their returned data. Will a success callback break this at all? Can I do $.when(ajaxCall1(), ajaxCall2(), ajaxCall3()).then(function(){alert('all three ajax functions definitely complete now!');}
@thomas: you can still have success callbacks in the individual ajax calls. The when will still get the results too. I've done that before and it does work just fine. And yes, your example should work ok
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.