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.
Related
I've been confused about callback functions for some time and I found a simple code snippet that illustrates my confusion. This is from w3schools:
var str = "Mr Blue has a blue house and a blue car";
var res = str.replace(/blue|house|car/gi, function (x) {
return x.toUpperCase();
});
This is a representative example of my confusion with callbacks. I don't understand how x in the argument function(x) is being populated. I'm looking at the documentation at MDN and I see that matches are being passed to x, but I don't understand the underlying principle. Is there a rule like " the argument of a callback function is populated by the previous argument," or is this behavior specific to String.replace()? How can I extrapolate and apply this to all callback functions that I find?
The replace function is called and passed two arguments.
The replace function (which is provided by the underlying JS engine, so its source code does not show up in your question) does stuff.
Among the stuff it does is call the function you pass as the second argument (newSubstr). When replace calls newSubstr, replace passes newSubstr an argument.
Is there a rule like " the argument of a callback function is populated by the previous argument,"
No. It is populated through whatever way the code calling the callback is designed to do.
this behavior specific to String.replace()?
Yes
How can I extrapolate and apply this to all callback functions that I find?
You can't.
Read their manuals or source code instead.
Just a couple of questions regarding using Nodejs in Web Development.
1) For my Concurrency question, it regards syntax. Is there a difference between:
setInterval(function() {
console.log('Task A');
}, 10);
and
function setInterval() {
console.log('Task A');
}, 10);
Also, i'm a little confused what the '10' means at the end of the method, my guess is the time it takes for the method to complete?
2) Callbacks - Are Callbacks just technically another name in Node for testing code?
3) Is there a method I can use in the Node(CLI) to see all of the methods in a module?
EX:
var fs = require('fs');
Obviously there are tons of methods in the File Systems module, but like the language Ruby, using PRY in the CLI, you can type 'fs.methods', which will display all of the methods. Then using 'cat', you can see the contents of each individual method. Something like this for Node(CLI)?
Thanks for all of the advice/answers!
Cheers,
G
1.
In the first, you pass in an anonymous function which will be invoked at the interval. Here you are using the node.js API setInterval.
In the second example, you are declaring a function called setInterval. Looks like a syntax error is there...
setInterval is a function that takes 2 objects in as parameters. That's it. the first parameter should be a function, and the second parameter should be a the the interval time in milliseconds. All that setInterval does is run the function passed in in the first parameter(a callback) every x milliseconds as specified in the 2nd parameter.
2.
No. Callbacks are functions that can be passed to other functions so that they can be "called-back" later in the code. Callbacks are pervasive in node.js applications and tightly related to it's asynchronous event based architecture. It is one of the most common patterns seen in node.js.
3.
Just look in node.js api docs on their website.
My recommendation to you would be to read about the node.js event loop and asynchronous programming.
First off, you're asking about some pretty fundamental aspects of Javascript so I'd suggest you work though some basic Javascript training because it will be hard to learn node.js if you don't already have a core understanding of the basics of Javascript. In particular callbacks are integral to much of nodejs coding.
Is there a difference between these two?
Yes, the two are completely different. One uses a built-in timer function, the other attempts to declare it's own function that has nothing to do with timers.
Let me explain your two examples:
The built-in setInterval function
setInterval(function() {
console.log('Task A');
}, 10);
Nodejs has a built-in timer function called setInterval. You can find the doc for it here.
You pass this function two arguments. The first argument is a function reference, the second argument is an amount of time in milliseconds. The nodejs timer infrastructure will call the function you passed it every N milliseconds.
It might be slightly easier to understand how setInterval works by seeing it used like this:
function myFunction() {
console.log('Task A');
}
setInterval(myFunction, 10);
This has the same output as your first example, but I think it shows more clearly how setInterval() is a built-in function that takes two arguments, a function and a number.
In your example, instead of the named function you are passing an anonymous function that simply does console.log('Task A'); and that function will be called every 10ms (approximately).
Create Your Own Function
function setInterval() {
console.log('Task A');
}, 10);
This block of code is a Javascript Syntax Error and will not work. It looks like you're attempting to define your own function called setInterval(), but this is not the proper syntax for declaring a function.
You could make it legal syntax like this:
function setInterval() {
console.log('Task A');
}
And, then you would call it like this:
setInterval();
This has nothing to do with the previous example. This just creates a function that runs once each time you call it. If you actually gave it the same name as the global function setInterval(), then your local definition would replace it within the scope it was declared.
Your Other Questions
Also, i'm a little confused what the '10' means at the end of the
method, my guess is the time it takes for the method to complete?
The 10 in the first example is the number of milliseconds for the interval timer. The 10 in the second example does not belong there - it's part of a Javascript syntax error.
Callbacks - Are Callbacks just technically another name in Node for
testing code?
No. A callback is when a function takes an argument that is a function reference (e.g. the name of a function or an anonymous function). When you pass a callback to this function, you can expect that the function will call the callback one or more times at some time in the future. When exactly it is called or how many times it is called depends entirely upon what the function does and how it is written. The term "callback" comes from the notion that this function will be "called back" some time in the future.
Is there a method I can use in the Node(CLI) to see all of the methods
in a module?
I'm not aware of a specific feature in the command line interface that will give you the methods of a module, but you can iterate them yourself or look at them in the debugger.
When you load a module in node with something like:
var fs = require('fs');
The object you get back from the require() function is a Javascript object. All the methods of that module are properties on that object. You can inspect that object in the debugger or with console.log(fs) or by writing code to iterate the properties of that object.
var fs = require('fs');
for (var prop in fs) {
if (fs.hasOwnProperty(prop)) {
console.log(prop);
}
}
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.
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);
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