Can Someone Explain me the Callback functions? - javascript

I've started recently to learn about javascript, and I saw a lot of callback functions.
What are those functions, why they are used and what for?
I will be happy to get really basic definition, because I wanna understand it because I realised that it is really important in js.
thanks :)

A callback function is a function you pass as an argument to another function.
The callback function will be called by the function you pass it to (or one further down the chain).
This is typically done when the function is doing something asynchronous, so you can't use a return value.
The main examples are for events:
// call someFunction when the document is loaded
addEventListener('load', someFunction);
or time related calls:
// call someFunction after 30 seconds have elapsed
setTimeout(someFunction, 30000);

As the name suggests, callback functions are anonymous or named functions that are passed as arguments to another function, or an AJAX call etc. and will be executed after a certain action is completed by the javascript engine.
For eg. You can pass a callback function to be executed once an AJAX call has returned with data. Ill use jQuery for simplicity :
$.ajax( {
url: "/my-api-path/",
data: myParams
}).done(myCallback);
Here, myCallback is a function that will be executed once the AJAX call completes. The callback function in this case will be called with the response object returned by the AJAX call. Notice how this callback has been passed as an argument to the .done method provided by jQuery's AJAX API.
In another example,
setTimeout(
function() {
alert("Im inside a callback function!");
}, 2000 );
Here the function that contains the alert is the first of the two arguments passed to the setTimeout method in javascript. The second being the amount of milliseconds after which this function should be executed. Since this function does not have a name it is called an anonymous function.
The same code could be re-written as :
var myCallback = function(){
alert("Im inside a callback");
};
setTimeout(myCallback, 2000);
Callbacks are executed immediately when the action completes. So after the engine encounters the setTimeout statement it will store the myCallback function in a reference and then continue execution after the setTimeout statement. Once 2 seconds elapse, it will realise its time to execute the callback so execution will jump to the callback. Then the alert will execute, the callback function will terminate and execution will continue back from where it was when 2 seconds elapsed and the engine jumped to the callback.
Hope this explains how callbacks work.

As we know we can pass different type of variable, object as function's parameter . In javascript if a function is passed as parameter then it is called Callback funbction.
The callback function is called on some event/condition till then the program can execute other code. The callback function would executed only when the particular event is occurred or particular condition is satisfied.

Related

Javascript callback function and an argument in the callback. How must it be used based on the code snippet provided?

I'm reading over a legacy codebase and I ran into this following code:
andThenWe: function(callback) {
var qunitAssertAsync = new window.AssertAsync(callback);
return qunitAssertAsync;
},
and here's the call site:
andThenWe(function(done) {
...(some code)
done();
});
So in the call site, we're passing in an anonymous function which will then be === 'callback' right? However, this callback has an argument called done and seems to be called at the end of this function. That argument is kind of like a block parameter in Ruby right? So somewhere in the window.assertAsync the callback MUST be called and passed some kind of arugment which is probably === to Qunit's assert.async right? (most likely). The details of the window.assertAsync are really complicated so I just want to understand at a high level what must be going on. Am I making proper assumptions?
This is all possible because callback in the function signature is an anonymous function that be invoked at a later time right? Also done itself in the callback function must be a function itself at runtime right?
I think this is an attempt to make qunit.async more "readable" (haha).
qunit.async is used to force tests to wait until an async operation has completed before exiting the test.
The done callback must be invoked when the writer of the test knows everything async has completed.

Understanding of callbacks

I've followed this explanation here, but am still unsure how callbacks work.
I do my call here:
scene.foo(scene.myCallBack("mymap"));
And my callback stuff here:
1) scene.foo calls foo and passes in CallBack function with "mymap" JSON data
2) foo's $.ajax defines its success as the passed in CallBack. Once the data is processed, success calls the callback, myCallBack()
3) myCallBack attempts to getJSON from the file name and console.log it as a string with JSON.stringfy
Am I not understanding this correctly?
foo : function (callback) {
$.ajax({
success: callback //once AJAX request is successfull, $.ajax will call callback (myCallBack) and pass response back to callback
});
},
myCallBack : function (name) {
$.getJSON("C:/Users/danniu/Desktop/JavaScript/tilemap/maps/" + name + ".json", function (data) {
var myJSONText = JSON.stringify(data);
console.log("json: " + this.myJSONText);
});
},
You're close to the solution.
scene.foo(scene.myCallBack("mymap")); first exectue scene.myCallBack("mymap") and then the result is passed to scene.foo(...)
It's similar to write:
var result = scene.myCallBack("mymap");
secene.foo(result);
This is pretty weird in this case, because scene.myCallBack("mymap"); doesn't return anything interesting to scene.foo
Note that $.getJSON(...) already does an Ajax request for you.
As soon as you stick parentheses on, it stops being a callback. scene.myCallBack can act as a callback; scene.myCallBack("mymap") is just undefined (the return value of your function, as it does not have an explicit return statement and thus implicitly returns undefined).
If you want to have he $.ajax do myCallBack on success AND have custom arguments with it, you need to wrap it:
scene.foo(function() { scene.myCallBack("mymap"); });
Or equivalently,
fooCallback = function() { scene.myCallBack("mymap"; };
scene.foo(fooCallback);
EDIT to clarify some concepts:
And can you explain why putting parentheses on it makes it not a callback?
Putting parentheses on a function executes a function, giving a value back. A callback must be a function.
For example, let's say your Mum wants you to eat an apple when you get home. She could leave you a note, "Growler, when you get home, eat an apple!":
var eatApple = function() {
growler.eat('apple');
}
growler.on('getHome', eatApple);
is one way to write such a thing. However, if you write
growler.on('getHome', eatApple());
it's like your Mum feeding you an apple, then writing a note "Growler, when you get home, __" and placing the apple core on the blank. I don't know about you, but I'd be rather surprised by such a note; and I daresay your JavaScript interpreter is likewise surprised as well.
A callback is a function to be done at a later time. If you execute it (with parentheses), you are only left with the function's results; and thus the function is not a callback, since your event will try to call back the result (the apple core), and not the function (process of eating an apple).
(An advanced topic is a function that returns a function; in this case, the result can be the callback, such as, growler.on('getHome', whatShouldIDoNow()). whatShouldIDoNow is still not a callback; the function that it would return would be.)
If $.getJSON is already an AJAX request, how can I get the callback from that?
I do not understand the question. You provide $.getJSON with callbacks at the time you invoke it; those functions will be called back at the appropriate time, if such happens.

Is this a correct way of JavaScript/jQuery callback?

This is a simple question. Here is my code:
$(document).ready( function () {
func1( "foo", callback);
function callback(param){
alert(param+" is my name");
}
function func1(name, cb) {
cb(name); // alerts "foo is my name"
callback("bar"); // alerts "bar is my name"
}
});
I want to know:
Which one of the function calls inside func1 is the correct callback and why?
Or are they both correct?
Isn't callback("bar"); a normal function call?
Callbacks are meant to let a caller specify what a function should do at some defined point in that function's execution. The function being called shouldn't know the name of that callback function ahead of time. So they'll often be passed to a function as an argument and the function that's supposed to call the callback should just invoke that argument.
When you call callback("bar") in func1, you're totally missing the point of callbacks. You may be invoking the function that you happen to use as a callback, but the point of callbacks is that func1 isn't supposed to know about that. It's just supposed to call the function that's been passed in as an argument (cb). When I'm calling func1 I should be able to pass a completely different callback function and func1 should just call that function without knowing what its name is (it may not even have one!).
The "correct" way is cb(name).
callback("bar"); is directly invoking the callback function where as cb(name); calls the reference passed to the func1,
cb(name); seems to be the correct way here.
First one. Function calls another one which has been pased as a parameter.
It seems like most jquery methods follow this this form for callbacks:
$(SUBJECT).method(function() {
//do stuff
}, /*callback here*/ function(){
//do stuff
});
like for instance
$(foo).click(function() {
$(bar).fadeIn(300, function(){
//call back here
});
});
fiddle

javascript - Order of executing functions

I have some javascript functions being called on Document Ready:
fogFields();
getLoS();
getShips();
startGame();
getNextMove();
However, it is as though getNextMove() is being called first, most likely as all it does is an ajax call and alerts the result. All the other functions have more work, so, the first thing that happens on load is the getNextMove() alert, and in the background you can see that none of the other functions did their work. Until I click OK on the alert window, no results are shown. Can I make it so that until a function finishes, the next wont even start. Some functions call their own extra functions before they finish, and that works in order, but I cant do that with the whole code...
Given the code in your question, there is no way the call to getNextMove can be invoked before startGame has been exited, regardless of their contents.
It may be true that a function that has been scheduled asynchronously (via timeout, AJAX callback etc.) within startGame completes at any time before or after the invocation of getNextMove, but this is a separate issue. To resolve that issue we need to know more about the contents of the functions.
If the other functions have an AJAX call in them, then these AJAX calls most certainly take a callback argument, which is a function that gets executes, when the AJAX call has finshed. Now, if you want to execute your functions in a way, the one function starts when the AJAX call of the previous function finished, you can add an additional callback argument to your own functions, which will then be passed to the AJAX calls. This should illustrate what I mean:
function logFields(callback) {
ajaxCall(callback);
}
function getLoS(callback) {
ajaxCall(callback);
}
function getShips(callback) {
ajaxCall(callback);
}
function startGame(callback) {
ajaxCall(callback);
}
function getNextMove() {
}
fogFields(function(){
getLoS(function(){
getShips(function(){
startGame(function(){
getNextMove();
});
});
});
});
If all of your functions use a ajax call then just use promises.
Simply return it, for example:
function fogFields(){
return $.ajax();
};
and then just use .then:
fogFields().then(getLos());
more information about deffered object on jquery doc page if you use it.
Or implementation in pure javascript you can find here and more theory here.
or another option, which I will not recommend you is to set async param in $.ajax call to false. Again it's for case you use jQuery.

callback in nested function

i have a function which calls the another function and so on.
function A(args,callback){
// make ajax request
// on response
B()
}
function B(args){
// make ajax request
// on response
C()
}
function C(args){
// make ajax request
// on response
D()
}
I am making such ten ajax calls. Two questions...
can anyone explain me what is callback-hell? Is this a callback Hell?
If i call callback() inside function D, will it get called. I am not passing callback as argument to my other functions.
I don't know what you're calling callback hell but it's one hell of a spaghetti code.
What is "callback hell"?
Asynchronous javascript, or javascript that uses callbacks, is hard to get right intuitively.
Source
2.No, callback is not defined inside D so you will get an Error.
Inside D() there is no way to call callback because it is not defined there. What I mean by this is as long as you don't pass arguments down the callbacks then you are not having your callback variable inside D(). Callback hell is a situation where callbacks call each-other meaning A() calls B() and B() calls A().
We can pass function reference as a parameter in JavaScript and use this reference to call related function whenever/ wherever we want.
for more info see this link http://recurial.com/programming/understanding-callback-functions-in-javascript/

Categories

Resources