2

Is there a way to add a callback to any given javascript function without changing its definition? Can this be done without using a library like deferred?

asked Nov 1, 2013 at 3:25
2
  • 1
    all js libs are implemented in js so yeah it's possible Commented Nov 1, 2013 at 3:27
  • 2
    No. A callback being passed to a function will only be useful if it is actually known by the function and then used by the function. So, the function's code HAS to be modified in order to use the callback. You can only use deferreds if the function was already written to work with deferreds. Commented Nov 1, 2013 at 3:38

1 Answer 1

6

You can make any function have a callback in javascript using the following function:

//takes a function fn, and returns a function that is exactly the same as fn
//except that it also takes a callback as the last argument
//and calls that callback with the return value of fn 
function makeCallbacked(fn){
 return function(){
 var callback = arguments[arguments.length-1];
 var args = Array.prototype.slice.call(arguments, 0, arguments.length-1);
 var result = fn.apply(this, args);
 callback(result);
 return result;
 }
}

Sample in console:

> var test = makeCallbacked(function(a,b){ return a + b });
undefined
> test(1,2,function(result){ console.log("result: "+result); });
result: 3
3 

If you want the callbacks deferred, you can make the slight modification:

//takes a function fn, and returns a function that is exactly the same as fn
//except that it also takes a callback as the last argument
//and defers a call to that callback with the return value of fn
//note that it may take a very long time for the callback to be called 
function makeCallbacked(fn){
 return function(){
 var callback = arguments[arguments.length-1];
 var args = Array.prototype.slice.call(arguments, 0, arguments.length-1);
 var result = fn.apply(this, args);
 setTimeout(function(){
 callback(result);
 }, 0);
 return result;
 }
}

Sample in console:

> var test = makeCallbacked(function(a,b){ return a + b });
undefined
> test(1,2,function(result){ console.log("result: "+result); });
3 
result: 3

Note that this is basically a really stupid thing to write, as you usually want to pass more interesting information to a callback than a return value, and you want the function to probably have better control over when the callback gets called. Just changing the function is probably for the best. It's also a huge waste of resources, if you care about that kind of thing.

answered Nov 1, 2013 at 4:43

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.