Passing the callback function as parameter from itself - javascript

Is it possible for me to pass a callback parameter to another method from within the callback function block itself? Example:
var resultCallback = function(result){
if(result)
{
alert('success!');
}else{
callServiceB(resultCallback );
}
}
callServiceA(resultCallback);
The reason of this is i wish to workout something like a Chain of Responsibility patterns in javascript.
Tried googled but so far gets nothing. Any idea or comment is welcomed.

Is it possible for me to pass a callback parameter to another method from within the callback function block itself?
Yes you can. Try it!
I wish to workout something like a Chain of Responsibility patterns
Putting both the responsibility chain (callServiceB(resultCallback)) and the resulting action (alert('success!')) in the same function looks like a bad practise/design smell. You should use an extra callback for the result, and separate the declaration of the chain from that.
It might then look like callServiceA(orCallServiceB(alertResult)) or either(callServiceA, callServiceB, …)(alertResult).
The logic is like 1. call function a 2. if function a ok, then call function b 3. if function b ok, then call function c, and so on.. – ipohfly 8 mins ago
That doesn't sound like a chain of responsibility, where you call the next function only if the current one failed (couldn't process the arguments)? What you describe sounds more like monadic chaining (one action relying on the previous one) - take a look at promises for that:
callServiceA.then(callServiceB).then(…).then(resultCallback);

Related

Want to understand need of callback functions in javascript

I am new in learning JavaScript. I read about callback functions but I am unable to understand its real use.
So, please help by any real world example.
Below is small code depicting use of callback function in but that too is not clear to me.
var friends = ["Mike", "Stacy", "Andy", "Rick"];
​
friends.forEach(function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
});
The uses of JavaScript callback functions are many. You probably already know that it's simply a function that we pass as an argument to another function. This means that we can have a function called foo. Lets says foo is some sort of method that runs an array through a sort, however the actual sorting function is variable. So we could use foo for every algorithm, by simply passing values like so.
foo([1,6,1,2], quickSort);
Assuming we have a quickSort method.
Generally speaking, callbacks are however used to call something AFTER a function has executed. So why not just call one function after the other, you say?
foo();
bar();
Why would you pass bar to foo ? Well, usually callbacks are used when dealing with asynchronicity. So, the bar function would get called way before, say an AJAX request gets a response, or before a setTimeout triggers it's callback.
As for the specific example you provided, it's simply a simplified way to iterate over an array. With the added benefit that you can use a named function, so you can declare it earlier and separate your code better.
Javascript is generally synchronous, i.e. commands are executed one after the other.
However there are times where you want a function to be asynchronous, so you call a function and don't want to wait for it to complete before you move on to your next task.
Callbacks are used by asynchronous functions. When the function completes, the callback function is run, without the rest of the code having to wait for it.
var friends = ["Mike", "Stacy", "Andy", "Rick"]; friends.forEach(function (element, index, array) { console.log((index+1) + "." + element ); });
The concept of Callbacks in JavaScript is that you can assign functions to variables.
Everthing, in JavaScript, except for simple types as string and number, are objects (and even those have functions to be called as they were objects as well).
Let's take your function for instance, as example:
Syntax
arr.forEach(callback[, thisArg])
Parameters
callback
Function to execute for each element, taking three arguments:
currentValue
The current element being processed in the array.
index
The index of the current element being processed in the array.
array
The array that forEach is being applied to.
thisArg
Optional. Value to use as this when executing callback.
It takes a callback function that will be called for each element.
Also, we have the definitions of asynchronous calls in JS (with a help of timeouts/interval and AJAX calls).
The idea of the callback functions doesn't stays just in JS. Anywhere it would be easier or just simples, to use a function passed as reference we have the concept of callback (it just goes insane with this feature of AJAX in js, that why it's so common to say JS is asynchronous).
You could read a litte more about it here:
http://www.sitepoint.com/javascript-goes-asynchronous-awesome/
In JavaScript, function below is an object:
function (eachName, index){
console.log(index + 1 + ". " + eachName); // 1. Mike, 2. Stacy, 3. Andy, 4. Rick​
}
Let call this object A.
When you pass the code friends.forEach(A), browser will understand that when running through the array friends it will trigger A.
So at the end, callback function is just like you "define" function but you will use it later on.

If a callback calls the enclosing function, would it be called a recursive call?

For example:
If http.request call is made in res.on('end') callback, then is the call recursive?
http.request(options, function(res) {
res.on('data', function(chunk) {
data+=chunk;
});
res.on('end', function(){
//do some stuff
http.request(options, function(res) {...});//is this recursive?
});
}).end();
Edit:
Let's take a simpler example: suppose there is a function which reads a file character by character:
var noOfChar = 10;
var i = 0;
readChar(function processChar(char){
if(i < noOfChar) {
console.log(char);
i++;
readChar(processChar); //is this recursive?
}
}
Rather than arguing about what to label it, let's consider some concrete attributes of your code, and how it is similar or different to what people usually mean by "recursive".
Usually a recursive function is something that grows the stack at each step (except for tail-call recursion, which uses a trick to prevent that growth). But in node, an asynchronous callback discards the stack of the outside context. (Try raising an exception inside the callback and see for yourself.) So this code does not grow the stack.
Also usually a recursive function is something that calls itself, but I don't see that happening anywhere in your example. The two listeners on http are different functions.
The second example doesn't call itself directly, but it does call itself indirectly. You have a "base case" (noOfChar >= 10) at which point the recursion unwinds. If readChar were synchronous you'd even be growing the stack. So this seems closer to recursive.
Notice that in your second example you have a named function, whereas the first example has only anonymous functions. In general I don't think recursion is possible without a named function (or at least some variable that holds the function), because otherwise how can a function refer to itself?
I don't think it'll be recursive if you are going to pass a different callback to it.
If you will pass same callback to both, it is going to be recursive.
Recursive means if I'm calling the same function in function definition itself. But if you are going to pass different callbacks it will be something like bellow.
Suppose you have 2 different callbacks callback1 and callback2.
You have passed first callback to outer http.request and second callback to inner http.request, so outer http.request will be executing the code given in callback1 but the inner will be executing code given in callback2.
I don't understand the meaning of the question.
Will you be flogged to death by your boss if the answer is yes?
Is there a law against recursivity?
http.request is only a means to an end. One way or another, you will need to call it more than once to process a transaction.
The trouble with your example code is that you handle an asynchronous exchange in one big lump of code, which handles the response directly without tracking the state of the transaction.
The only comment that comes to my mind is that this kind of logic is extremely fragile, because the termination conditions are dependent on whatever parameters are passed to your requests, leaving the door open to a score of potential problems like out of sync answers and infinite loops (whether they deserve the name of "recursive calls" is of little interest if they hang the system in the end).
I would rather advise to build an explicit state machine to track the progress of intended HTTP exchanges, which would dispense of philosophical questions about recursivity and the associated "good practices".
I'm going to try to answer my own question because I think now I understand Recursion a bit better. Maybe this will help someone else.
My doubt was if a function invokes a callback, which calls the function again would it be called recursion. I feel it is similar to indirect recursion where function1 calls function2 and function2 calls function1 again. So it doesn't matter if function1 calls function2 which calls function3 which in turn call function1 again, it is still recursive. In the same way it shouldn't matter if function invokes a callback which invokes another callback which calls the function. If second example is recursive, first can also be recursive.
Recursive solution to a problem has to do more with how the problem is solved than the language implementation like growth of stack. Take tail-recursion for consideration, it doesn't increase call stack, yet no ones questions about it's recursiveness.
So the key point is to think recursively. Take the whole problem, if a part of it can be solved in the same way as the original problem then the solution is Recursive. A function calling itself may not qualify for being recursive. Some may call it self referencing functions but not recursive.
Recursion should at least consist of a base case and a recursive case, each self-reference should bring the input value closer to the base case which would end the recursion.So I think both of the examples mentioned in the question are not recursive.
Recursive calls may not result in increase in call stack. There is tail call recursion which keeps call stack size constant.
Take the following examples which consist of callbacks, here outer function stack frame may or may not be in memory.
var input = [[1,2,3],[4,5,6],[7,8,9]];
function double(ip) {
return ip.map(function (element) {
if(Array.isArray(element)) {
return double(element);
}
else {
return 2 * element;
}
});
}
console.log(double(input));
I would call it as recursive. Also we can do Anonymous Recursion, so explicitly naming a function isn't necessary.

Alternative approach to force sequential javascript execution

I am looking for a way to execute multiple functions in JavaScript and force them to run sequentially. The most straight forward way to achieve this is to use callback functions (which has been the most commonly found suggestion on this forum and elsewhere). The problem with callback functions is that the resulting code can easily become hard to read as the result may be a lot of nested callback functions.
Am wondering if the following code will execute sequentially as well:
function doSomeThingOne(){
//do something intense here that takes quite some processor time
void(0); //dummy statement for illustration purposes only
return true;
}
function doSomeThingTwo(){
//do something intense here that takes quite some processor time
void(0); //dummy statement for illustration purposes only
return true;
}
function testSequentialExecution(){
//a temporary variable just to capture the
var bolTemp=false;
//execute the first function
bolTemp=doSomeThingOne();
//after this is done, execute the second function
bolTemp=doSomeThingTwo();
}
//kick off the (hopefully) sequential execution
testSequentialExecution();
Am looking for a plain JavaScript solution.
If my functions doSomeThingOne() and doSomeThingTwo() do not execute code that runs a-synchronically (like a typical AJAX request) will this coding-style force the functions to execute synchronically?
Yes, of course. That works just the same way JavaScript doesn't shuffle the content of any other function - expressions in a function will always be executed in order. Specifically, all expressions inside of a code block (something between {}) will always be executed in order. A function body is such a code block.
The expression might have async side effects (like calling setTimeout() or making AJAX calls) but the expression itself is evaluated in order. The browser can just determine to keep references to part of the expression and execute those parts later.
Your question seems like you spent too much time in the async world ;-)
The main problem is usually that you do something async. And then, the function ends and eventually, the callback will be called. There is no good way to serialize this. Maybe JavaScript promises will help.

How to pass additional arguments to callback functions in javascript when using .execute()?

I'm working with javascript for Google Analytics API but I'm no more than a novice in JS. I have C++ and Java knowledge and I can get along with logical thinking but some things puzzle me. In GA API I get to make a function call like this:
gapi.client.analytics.data.ga.get({'ids':'<tableID>',
'start-date':'<startDate>',
'end-date':'<endDate>',
'metrics':'<metrics>',
'filters':'<filters>',
'samplingLevel':'HIGHER_PRECISION',}).execute(putToVar);
putToVar() is a user defined function defined like so:
function putToVar(results)
{
//do processing with the results
}
It is my understanding that the .execute() method is used to invoke a callback function for the asynchronous call gapi.client.analytics.data.ga.get(). So I assume what function1().execute(function2) does is call function2 with the return value from function1 as argument? Is this correct?
I'm in a situation where I need to apply several distinct filters and store them in an array to retrieve as and when required, irrespective of whether the API call returned a results object (it is an async call, so I don't know when the response comes, it is only visible to the callback function).
I would like to pass to the callback function the dimensions of the array in which to store the returned objects so that I can retrieve them on demand later, without worrying about the order in which the responses get processed. I say this because, initially I tried a for loop and the order in which I got the response to my API calls were not the same as the order in which I placed API calls for my queries, so there were mismatches.
Since the reference uses this method to invoke the callback function, I would like to know how to pass additional arguments to a callback function like this when using .execute() method, when I get to write putToVar() function something like this:
function putToVar(results,arrayDim)
{
//Process Results
//Store in Array[arrayDim] the required value
}
I hope I have made myself clear.
I have read the following posts
How do I pass multiple arguments into a javascript callback function?
passing arguments to callback
How to explain callbacks in plain english? How are they different from calling one function from another function?
How to pass additional arguments to callbacks and also access default parameters?
but none of them seem to use the .execute() method and I cannot figure out how to use what they have said. Or, if and how my .execute() method (type of callback execution) can be modified to help my purpose.
Adding a closure would solve your problem:
for(var x = 0; x< n x ++){ //Or any other loop
(function(x){ //Closure. This line does the magic!!
var arrayDim = something_that_depends_on_x_or_the_loop,
param2 = some_other_thing_that_depends_on_x;
gapi.client.analytics.data.ga.get({'ids':'<tableID>',
'start-date':'<startDate>',
...
}).execute(function putToVar(results){ //this fn is defined inline to get access to param1, param2
//The following alerts will use the *correct* variables thanks to the closure
alert(x);
alert(arrayDim);
alert(param2);
});
})(x); //This one too
}
The closure does the magic. It will allow to each loop cycle to have its own variables (not shared), so the proper ones will be inside putToVar when executed.
I hope it's clear, if not, just let me know.
Just test it!
Cheers, from La Paz, Bolivia

why is it necessary to wrap function call in a function body

I often see something like the following in JavaScript:
$("#sendButton").click(function() {
sendForm();
}
Why is it necessary to wrap the call to sendForm() inside a function? I would think that doing it like this would be more readable and less typing.
$("#sendButton").click(sendForm);
What are the advantages/disadvantages to each approach? thanks!
There's typically two cases where you'd want to use the former over the latter:
If you need to do any post-processing to the arguments before calling your function.
If you're calling a method on an object, the scope (this reference) will be different if you use the second form
For example:
MyClass = function(){
this.baz = 1;
};
MyClass.prototype.handle = function(){
console.log(this.baz);
};
var o = new MyClass();
$('#foo').click(o.handle);
$('#foo').click(function(){
o.handle();
});
Console output:
undefined
1
Probably one too many answers by now, but the difference between the two is the value of this, namely the scope, entering sendForm. (Also different will be the arguments.) Let me explain.
According to the JavaScript specification, calling a function like this: sendForm(); invokes the function with no context object. This is a JavaScript given.
However, when you pass a function as an argument, like this: $(...).click(sendForm), you simply pass a reference to the function for later invocation. You are not invoking that function just yet, but simply passing it around just like an object reference. You only invoke functions if the () follows them (with the exception of call and apply, discussed later). In any case, if and when someone eventually calls this function, that someone can choose what scope to call the function with.
In our case, that someone is jQuery. When you pass your function into $(...).click(), jQuery will later invoke the function and set the scope (this) to the HTML element target of the click event. You can try it: $(...).click(function() { alert(this); });, will get you a string representing a HTML element.
So if you give jQuery a reference to an anonymous function that says sendForm(), jQuery will set the scope when calling that function, and that function will then call sendForm without scope. In essence, it will clear the this. Try it: $(...).click(function() { (function() { alert(this); })(); });. Here, we have an anonymous function calling an anonymous function. We need the parentheses around the inner anonymous function so that the () applies to the function.
If instead you give jQuery a reference to the named function sendForm, jQuery will invoke this function directly and give it the scope that it promises to always give.
So the answer to your question becomes more obvious now: if you need this to point to the element target of the click when you start work in sendForm, use .click(sendForm). Otherwise, both work just as well. You probably don't need this, so skip the anonymous function.
For those curious, scope can be forced by using the JavaScript standard apply or call (see this for differences between the two). Scope is also assigned when using the dot operator, like in: obj.func, which asks of JavaScript to call a function with this pointing to obj. (So in theory you could force obj to be the scope when calling a function by doing something like: obj.foo = (reference to function); obj.foo(); delete obj.foo; but this is a pretty ugly way of using apply.
Function apply, used by jQuery to call your click handler with scope, can also force arguments on the function call, and in fact jQuery does pass arguments to its click handlers. Therefore, there is another difference between the two cases: arguments, not only scope, get lost when you call sendForm from an anonymous function and pass no parameters.
Here you are defining an anonymous event handler that could call multiple functions inline. It's dirty and tough to debug, but people do it because they are lazy and they can.
It would also work like your second example (how I define event handlers):
$("#sendButton").click(sendForm)
Something you get by defining your event handlers inline is the ability to pass event data to multiple functions and you get this scoped to the event object:
$("#sendButton").click(function(event) {
sendForm();
doSomethingElse(event);
andAnotherThing(event);
// say #sendButton is an image or has some data attributes
var myButtonSrc = $(this).attr("src");
var myData = $(this).data("someData");
});
If all you are doing is calling sendForm, then there isn't much difference, in the end, between the two examples you included.
$("#sendButton").click(function(event) {
if(event.someProperty) { /* ... */ }
else { sendForm({data: event.target, important: 'yes'}); }
}
However, in the above case, we could handle arguments passed to the callback from click(), but if the sendForm function is already equipped to handle this, then there's no reason why you wouldn't place sendForm as the callback argument if that is truly all you are doing.
function sendForm(event) {
// Do something meaningful here.
}
$("#sendButton").click(sendForm);
Note that it is up to you where you handle the differing layers of logic in your program; you may have encapsulated certain generic functionality in a sendForm function then have a sendFormCallback which you pass to these sorts of function which handle the interim business of event/callback processing before calling sendForm itself.
If you are working in a callback-heavy environment, it would be wise to separate significant functionality from the callback triggers themselves to avoid callback hell and promote maintainability and readability in your source code.
It's just to lock scope. When you wrap that sendForm() in the anonymous function that closes over the current scope. In other words, the this will be kept with it. If you just pass sendForm then any calls to this will come from the calling scope.
This is a good question for learning about scope in javascript, and questioning conventions.
Nope, that second example is perfectly valid.
99.9% of jQuery examples use the first notation, that doesn't mean you need to forget basic JavaScript syntax.

Categories

Resources