I've been reading about some documentation on Callbacks and Hooks for a meteor application I'm making, which uses the Aldeed Autoform package. I was told hooks would be helpful to me in something that I wanted to do, but I cant actually figure out what Callbacks and Hooks are. An explanation or even a link to a site that explains it would be great, thanks!
A callback is a function that is passed as a parameter to another function:
// Function that accepts a callback
function greet(name, callback) {
var greeting = 'Hello ' + name + '!';
callback(greeting);
};
// Call greet function with name, and anonymous function
greet('Dave', function(greeting) {
alert(greeting); // 'Hello Dave!'
});
It's particularly useful when you want to do something asynchronous, where you don't know how long the process will take, or when it will be completed e.g an AJAX request. You can wrap up the logic you want to be completed after the request has come back in a function, e.g updating the DOM, and it will be executed whenever it needs to be.
Related
I realise this is more of a general question, but I've read through similar answers on here but I can't find more of an overview. I'm new to callbacks and I'm trying to understand when they should be used.
The MDN web docs has this example;
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput(callback) {
var name = prompt('Please enter your name.');
callback(name);
}
processUserInput(greeting);
However I'm struggling to see how this is more beneficial than the following, where I'm not passing the greeting function as a parameter?
function greeting(name) {
alert('Hello ' + name);
}
function processUserInput() {
var name = prompt('Please enter your name.');
greeting(name);
}
processUserInput();
As Javascript is async, sometimes it is difficult to handle response from non-blocking functions, for ex. if you are making an ajax call then it'll be executed asynchronously and results will be returned sometime later, by that time the main execution flow will pass the ajax code and starts executing following statements, in that case, its very difficult to catch the response to process further.
To handle those cases, callbacks comes into picture where you pass a function as the parameter to the ajax function and once the response is returned then call the callback by passing response data as a parameter to process further.
more info here http://callbackhell.com/
In simple terms you can say a callback is a way of asking a question (or requesting a task) in advance, i.e. when you're done with this do this (usually with the result). The whole point is to set aside functions that are to be done later, usually because you don't have the required inputs to do them now.
The 2 main differences between your implementation and the MDN one is that yours is harder to maintain and harder to reason about hence test.
1. Maintanance / Reusability
Imagine you're a few thousand lines of code into a code base then you're required to change what processUserInput() does. Its much easier to change or write a new callback function instead of changing the function processUserInput(). This would be evident if processUserInput was a bit more complicated. This also means the MDN one is much more useful in various scenarios unlike your implementation. You can reuse it in different situations like saying good bye, capitalizing names etc simply by writing different callbacks to plug into processUserInput().
2. Testing / Easier to reason about
The MDN implementation is much more easier to understand. Its easier to assume that the function processUserInput(greeting) will probably return a greeting than it is to assume what processUserInput() does. This makes it easier to test because you can always be sure the MDN implementation will always return the same output given an input.
Callbacks can be extremely useful depending on the circumstances; for example, when working with JavaScript for Google Chrome browser extension development, a callback can be used for intercepring web requests once it has been setup.
The purpose of a callback in general is to have the callback routine executed upon a trigger - the trigger being an event of some kind. Usually, functionality follows an interface of chained APIs. By implementing callback support, you can redirect execution flow during a stage of an operation. Callbacks are especially useful to third-party developers when dealing with someone elses library depending on what they are trying to do. Think of them like a notification system.
Functions in general taking in parameters is useful for flexibility and maintenance. If you use different functions for different things, the functions can be simply re-used over and over again to provide different functionality - whilst still preventing bloating the source code with more-or-less the same code over and over again. At the same time, if you use functions to your own library and a bug shows up, you can simply patch it for the one function and then it will be solved.
In your example, your passing a callback routine to the function you're calling - the function you're calling will call the callback function and pass the correct parameters. This is flexible because it allows you to have a callback routine called for printing the contents of the variable, and another for calculating the length of the string passed in, or another for logging it somewhere, etc. It allows you to re-use the function you setup, and have a different function called with the correct parameters without re-making the original function.
This example is not appropriate for understanding callbacks
In simple Language callbacks functions are used when we have to do some stuff after or in response of some other event or function or expression.
i.e when the parent function completes its execution then callback gets executed.
simple Example
function hungerStatus(status,cb){
return cb(status)
}
function whatToDo(status){
return status ? "order Pizza" : "lets play"
}
hungerStatus(false,whatToDo)
Another example
// global variable
var allUserData = [];
// generic logStuff function that prints to console
function logStuff (userData) {
if ( typeof userData === "string")
{
console.log(userData);
}
else if ( typeof userData === "object")
{
for (var item in userData) {
console.log(item + ": " + userData[item]);
}
}
}
// A function that takes two parameters, the last one a callback function
function getInput (options, callback) {
allUserData.push (options);
callback (options);
}
// When we call the getInput function, we pass logStuff as a parameter.
// So logStuff will be the function that will called back (or executed) inside the getInput function
getInput ({name:"Rich", speciality:"JavaScript"}, logStuff);
refer callback exaplanation
I come from a C/C++ background and I'm having real trouble trying to wrap my head around the syntax of node.js. Anyway, I found some code online to explain the difference between blocking and non-blocking code, and it's had me stumped for hours. I've tried searching and reading books but just can't find an answer to this. The example code retrieves a user ID from a database.
Blocking Version:
function getUser(id) {
var user = db.query(id);
return user;
}
console.log('Name: ' + getUser(432).name);
Non-Blocking Version (Node.js):
function getUser(id, callback) {
db.query(id, callback);
}
getUser(432, function (user) {
console.log(user.name);
});
I'm fine with the Blocking version because in that instance, the user ID is assigned to the variable user. What I just can't seem to understand is the user argument in the anonymous function. It seems that user just appears out of nowhere and then has instructions acted upon it, without any relationship to an existing variable.
How does the program know what user is? How does it even make any connection with the user's ID? I honestly can't tell if it's my lack of knowledge of JavaScript/Node, or whether the person who wrote this code didn't bother to complete it. All I know is, this makes no sense in C/C++.
Well, you've asked the program to fetch you a user, and supplied with a function that accepts an argument (or more, depending on the library). After the operation is complete, getUser will invoke the callback you passed with the result of the operation.
Here's a dummy getUser implementation for you:
function getUser(id, callback) {
setTimeout(function() {
var result = {id: id, name: "Madara"};
callback(result);
}, 1000); // Wait a second before doing it. Asynchronous!
}
getUser(42, function(user) { console.log(user); });
That function will wait one second, and then invoke the callback you pass with one argument, in this case, an object with the ID you passed, and "Madara" as the name.
Notice that there's nothing blocking with getUser, so getUser returns immediately, and without waiting for the callback to be called.
Maybe it will help you if I translate your example into C.
I haven't used C in a long time but I think it would look like this.
void getUser(int id, void (*callback)(User)) {
db.query(id, callback);
}
void printUserName(User user) {
printf(user.name);
}
getUser(432, &printUserName);
How do I set an object's properties from an asynchronous function without losing the values? Someone on another SO thread said that anything that has to do with this function should be kept inside the function. However,I want to assign values from it, and assign it to an object. I'm a little new to OOP Js, so this was confusing to me.
I have this function that gets the user's location. This HTML5 function requires a callback to pass a position object into.
function getInfo()
{
navigator.geolocation.getCurrentPosition(getPos);
}
This is the function that is referenced in getCurrentPosition().
function getPos(position)
{
PositionObj.lat = position.coords.latitude;
PositionObj.lon = position.coords.longitude;
}
PositionObj:
var PositionObj =
{
lat:null,
lon:null,
returnLat: function()
{
return this.lat;
},
returnLon: function()
{
return this.lon;
}
};
When I try to access PositionObj's properties, I get null, and not the new value that was assigned by the callback. How do I go about doing this? I've tried things like making the callback an object itself, and passing the values to another function that assigns values to the object. Any help would be appreciated!
The most important question is: when are you trying to access PositionObj's properties? Since the whole thing is asynchronous, you won't see any value in lat or lon until the location is retrieved and getPos assigns it. Thus, something synchronous like:
getInfo();
console.log(PositionObj.lat);
is definitely not going to work. getInfo returns immediately and doesn't wait for the location to come in. That's a good thing: the whole idea about asynchronism is that you don't wait (block) until you get your results. Instead, you give a callback to the function and that function makes sure to call it when the results are retrieved later on. In Hollywood style: "don't call me, I call you!"
Thus, anything that relies on the actual position retrieved by getInfo needs to be in the callback. This means that you have to think and code differently: you'll need to break up your synchronous function into smaller functions which are chained up as callbacks.
In your case, you'd put that console.log(PositionObj.lat) (or anything else you want to do with the position) inside (what you called) getPos (you probably want to think of a better name for that function though).
Here's a more complete example which demonstrates the concept better. An online shop may have something like this on its checkout page:
var position = getPosition(); // using geolocation
var closestShop = getClosestShop(position); // using AJAX to a server-side script
alert("The closest shop is " + closestShop);
However, all those synchronous calls would block the script's execution and the page would "freeze". The user would probably think that his browser crashed, and that's not a great user experience.
If all these actions were asynchronous, you'd restructure it so it looks like this:
getPosition(function(position) {
getClosestShop(position, function(closestShop) {
alert("The closest shop is " + closestShop);
});
});
Here, each function accepts a callback function which it calls when the results are in. They all return immediately, allowing the script to continue execution and keep the page responsive. Of course, nothing stops you from starting another asynchronous action from within this callback, effectively chaining them up.
In fact, this last pattern is so popular that a new mechanism was created to make it more manageable: promises. The inner workings are still the same (functions accepting a callback instead of blocking synchronously) but it looks more pleasant. When you make getPosition and getClosestShop return a promise, you could write:
getPosition().then(getClosestShop).then(function(closestShop) {
alert("The closest shop is " + closestShop);
});
I understand the basic thing about asynchronous-ness: things don't execute sequentially. And I understand there is something very powerful about that... allegedly. But for the life of me I can't wrap my head around the code. Let's take a look at async Node.JS code that I HAVE WRITTEN...but don't truly get.
function newuser(response, postData) {
console.log("Request handler 'newuser' was called.");
var body = '<html>' +
'<head>' +
'<meta http-equiv="Content-Type" content="text/html; ' +
'charset=UTF-8" />' +
'</head>' +
'<body>' +
'<form action=" /thanks" method="post">' +
'<h1> First Name </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<h1> Last Name </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<h1> Email </h1>' +
'<textarea name="text" rows="1" cols="20"></textarea>' +
'<input type="submit" value="Submit text" />' +
'</body>' +
'</html>';
response.writeHead(200, { "Content-Type": "text/html" });
response.write(body);
response.end();
}
Where did response come from again? postData? Why can't I define a variable in this "callback" and then use it outside of the callback? Is there a way to have a few things be sequential then the rest of the program async?
I'm not sure where this function is being used, but the point of callbacks is that you pass them into some function that runs asynchronously; it stores your callback away, and when that function is done with whatever it needs to do, it will call your callback with the necessary parameters. An example from front-to-back is probably best.
Imagine we have a framework, and in it there is an operation that runs for a long time, fetching some data from the database.
function getStuffFromDatabase() {
// this takes a long time
};
Since we don't want it to run synchronously, we'll allow the user to pass in a callback.
function getStuffFromDatabase(callback) {
// this takes a long time
};
We'll simulate taking a long time with a call to setTimeout; we'll also pretend we got some data from the database, but we'll just hardcode a string value.
function getStuffFromDatabase(callback) {
setTimeout(function() {
var results = "database data";
}, 5000);
};
Finally, once we have the data, we'll call the callback given to us by the user of the framework's function.
function getStuffFromDatabase(callback) {
setTimeout(function() {
var results = "database data";
callback(results);
}, 5000);
};
As a user of the framework, you'd do something like this to use the function:
getStuffFromDatabase(function(data) {
console.log("The database data is " + data);
});
So, as you can see data (same as response and postData in your example) came from the function that you pass your callback into; it gives that data to you when it knows what that data should be.
The reason you can't set a value in your callback and use it outside the callback is because the callback itself doesn't happen until later in time.
// executed immediately executed sometime in the future
// | | by getStuffFromDatabase
// v v
getStuffFromDatabase(function(data) {
var results = data; // <- this isn't available until sometime in the future!
});
console.log(results); // <- executed immediately
When the console.log runs, the assignment of var results hasn't happened yet!
You have several unrelated questions here:
1) The power of async is being able to do multiple things at the same time without locking the main thread. In node and js in general, this applies particularly to ajax file requests. This means that I can fire off several async calls to retreive files, and not lock the main thread while it renders the content. My preferred framework is jQuery, which has convenient $.Deferred that wraps and standardizes async calls for jQuery usage.
2) response and postData come from the parent method. There's nothing magical here, it's a normal function call, so the values of these are created elsewhere and passed into this invocation. Depending on which node framework you have, the exact signature of your method will change.
3) You can define a global variable in your callback if it's properly scoped. It seem though that you need help learning what scope is. Here are some links
http://www.digital-web.com/articles/scope_in_javascript/
http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/
4) Once you go async, you can never go back, however, by leveraging promise and deferred objects like with jQuery Deferreds you can wait for several asyncs to complete before continuing your execution in yet another async. Deferreds are your friends.
http://api.jquery.com/category/deferred-object/
Looks like you're working through the Node Beginner Book. I encourage you to work through the entire book, it really is an excellent introduction. If you are trying to understand Javascript better, Douglas Crockford's videos on YouTube are a great overview: 1, 2.
The piece of code you've posted doesn't have enough context for me to really help you. response is a parameter that you're passing to your function, it does not come from postData. If you are working with code the way the Node Beginner Book suggests, you are probably passing response to your newuser function all the way down from the createServer function, which is part of the http module that comes with Node.
You can't define a variable in the callback and then use it in the callback because Javascript is lexically scoped. Here's a Stack Overflow post on the topic of Javascript's scope. The first video by Doug Crockford that I posted also has a great explanation of Javascript's scoping rules.
Javascript isn't necessarily async. It simply provides anonymous functions that are closures, which are a useful tool for easily implementing async logic. Again, the Node Beginner Book shows a good example of writing synchronous code with Node (not what you want), then rewriting it to make it async.
I am very new to JavaScript and need to use callback function in my java script function. I don't know how to use a callback function. Below is my code:
function SelectedFeature() {
// Here is my code call_Method1();
call_Method2();
}
The problem in the above function is that, call_method2() starts executing before call_Method1() ends its execution. To solve this problem, someone told me to use a callback function. Now how can I use callback function in my SelectedFeature() function? Please explain by using code sample.
I'm making an asynchronous request in call_method1(). I need call_Method2() should be called after completing execution call_method1(). But in my case, call_method2() calls before call_method1() completes its execution. Now how can I fix this?
You have to refactor call_method1() to accept and execute a callback after it finished execution:
call_method1(call_method2);
and
function call_method1(callback) {
// ...
// do asynchronous stuff, when the response is processed, call
if(typeof callback === 'function') {
callback();
}
// ...
}
Functions are first class citizens, so by referring to them by their name, you can pass them around like any other value.
We could help better if you post the code for call_method1.
What are you using to do your asynchronous call? Did you code it yourself or are you using a library like JQuery?
You could simply put a bool to say "working" that you set to true as method 1 starts and back to false when it finishes. you could then have method2 wait while working is true.
The question has already been answered above by Felix. Inspired by his answer and an issue I am having in a current project, I wrote a little gist that has a class that adds up a little extra safety.
To sum up, you pass a callback function just as the way you pass a variable. Then the receiver will trigger it as a function.
myCoolFunction: function( data ) {
// Do some thing with response
}
$.get( '/some/cool/url', myCoolFunction );
In the above $.get calls back myCoolFunction with the parameter data once the data is fetched
What happens if myCoolFunciton is a variable. Well it depends on how the receiver handles the input.
Just to be careful, I have a CoffeeScript class ( and its JavaScript compilation ) that will do some safety checks.
It doesn't do any thing magic, checks if its a function and returns, if not returns an empty function so that it would reduce possibility of JS error. https://gist.github.com/ziyan-junaideen/8717925