views:

80

answers:

7

How can I create a function, that will call another function, and when it completes, fire another callback function?

so existing functions are:

function f1(..) {..}

function myCallback() {...}

Now is it possible to make f1 fire and finish, THEN run myCallback()?

+12  A: 

Provide a function reference as a parameter to the function you're calling.

function f1(fn) {

  // ...

  if (typeof fn === 'function') {    
    fn();
  }
}

// can be a defined function name or a variable holding a reference to a function
f1(myCallback);
lincolnk
And of course `fn` can also be an anonymous function. ==> `f1(function() { ... });`
Peter Ajtai
@Peter also correct, thanks :D
lincolnk
Only problem with this is that if you can't modify "f1", you're kind-of stuck.
Pointy
@Pointy can't modify f1 how?
lincolnk
Like if it's in a script file that you import from another website ...
Pointy
+1  A: 
f1();
myCallback();

… unless f1 is asynchronous, in which case f1 would have to be edited to accept a callback and run it when it is finished. Since there are multiple things that could make a function asynchronous, it isn't possible to give a simple "…and this is how" answer without a lot more detail.

David Dorward
you right, well f1 is an ajax call so you have to wait for it to finish. i dont' have access to modify f1.
Blankman
Then you are stuck. f1 is a black box which doesn't let you modify the bit you need to modify.
David Dorward
look at @pointy's response, it didn't (yet?) work but got my hopes up!
Blankman
@pointy's response is, basically, a generic and reusable version of my code above.
David Dorward
A: 
function f1(myCallBack)
{
// f1 activities 


myCallBack();
}
sushil bharwani
4 spaces before a line formats as code. To do this with a block, select it and type `ctr-k`
Peter Ajtai
+1  A: 
function f1(param1, callback){
    // Do Work
    callback();
}

function myCallback(){
    // Do Callback Work
}

And then call f1 like:

f1(parameterValue, myCallback);
Justin Niessner
A: 

if f1 is just a simple javascript-function it runs synchonous, so you just have to call myCallback after it/at the end of f1. if if does some crazy ajax-stuff (with jquery in your case), there you can set a callback on these ajax-things.

oezi
A: 

You could create a facility to let you bind "onfinish" functions to any function:

function bindFollowup(f, followup) {
  return function() {
    f.apply(this, arguments);
    followup && followup();
  };
}

Then you can just define f1 and then write:

f1 = bindFollowup(f1, myCallback);
Pointy
nice, if htis works its perfect since I can't modify f1 at all.
Blankman
Blankman
Calling `followup` if you passed it in to the factory.
David Dorward
@Blankman it's just a check to make sure "followup" isn't null. It's kind-of lame and you'd probably want to make sure it's actually a function (in addition to not being null or undefined).
Pointy
A: 

lincolnk provided a great answer. It can be made much more flexible using the arguments array:

function f1() {
  var i;
  // ...
  for (i = 0; i < arguments.length; ++i)
  {
      if (typeof arguments[i] === 'function') 
      {
          arguments[i]();
      }      
  }

}

Like this, you can pass in as many callback functions as you want. They will be executed in the order passed in. No harm is done if the argument is not a callback.


Finally, you can preserve the context and arguments of f1 using apply().

Preserving the context could definitely be useful in many situations. I'm not sure about the arguments, but it is an option.

function f1() {
  var i;
  // ...
  for (i = 0; i < arguments.length; ++i)
  {
      if (typeof arguments[i] === 'function') 
      {
            // You can leave off 'arguments', but preserving 'this' will 
            //   often be useful.
          arguments[i].apply(this, arguments);
      }      
  }

}

the above allows you to do things like:

f1("alert me",function() {alert(arguments[0]);});
// Output when the call back is called: 
//    "alert me" 

jsFiddle example

Peter Ajtai