Is this a correct way of JavaScript/jQuery callback? - javascript

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

Related

Why do we need callback instead of calling directly inside the function? in JS

I just realized that I do not understand javascript enough, despite the fact that I have been coding it for some time.
What I am not comfortable is Javascript Async.
until now I have been using callback and promise, because documentations and tutorials did it so as below.
$.get("some/url", function() {
// callback body
})
axios.get('some/url').then(res => {
console.log(res.data);
});
arr.map(element => console.log(element))
I know callback is used to my our code asynchronous
function doSomething(cb) {
console.log("this function receives callback function");
cb();
}
but what if we just call the function inside the function manually
function func1() {
// function body
}
function doSomething() {
console.log("this function receives callback function");
func1();
}
What I thought is as long as function is called at the right time, we do not have to use callback.
or is it because callback does its work while some other operations are going on?
If so, doesnt it break the principle of javascript as single threaded?
because its doing two things at the same time.
besides, do people use promise over callback function because of its readability and you could use Promise.all() ?
I feel like I am missing a core advantage of using promise.
Kindly please help me understand better.
If you don't use a callback, then you can only call func1(). The original doSomething() is more general, since you can call different functions depending on what the caller needs.
function func1() {
// function body
}
function func2() {
// function body
}
doSomething(func1);
doSomething(func2);
Is exactly the difference between hard coding data in your code or getting it dynamically.
In backend for example you make the code so it can serve different users different needs... at the same time, the same code...
So in this example:
function doSomething(cb) {
console.log("this function receives callback function");
cb();
}
you can build a functions that serve different users different information depending on the cb it receives...
in this example:
function func1() {
// function body
}
function doSomething() {
console.log("this function receives callback function");
func1();
}
it just runs a specific function func1 and that's it
It is all about reusability. If you call pass your callback into the utility function, in your example it is doSomething, you will not be able to reuse doSomething function in other parts of your program. You have just created a tight coupling between two functions.
If you program to the interface, and define which kind of callback you are expecting in your doSomething function, you will be able to use this doSomething function anywhere. It will not have to know which exact function to call, it will just concern about having a callback which expects n parameters in some order which.

(Why) does jQuery .click() require a callback function?

I have the following jQuery code:
function next() {
//some code here
}
function previous() {
//some code here
}
$("#next").click(function(){
next();
});
$("#previous").click(function(){
previous();
});
This works, but this doesn't:
$("#next").click(next());
$("#previous").click(previous());
Why is this happening? Is there a problem in my code, or is this just a thing with jQuery? Note: #next and #previous refer to two buttons in my html file.
The callback should be a reference to the function.
Why $("#next").click(next()); doesn't work?
func() is a function call and not a reference, which is why it is called immediately.
This,
$("#next").click(function(){
next();
});
is a preferable way in case you need to pass arguments.
Else,
$("#next").click(next) //notice just the signature without ()
This works (if the functions next and previous are defined):
$("#next").click(next);
$("#previous").click(previous);
In this case the next and previous are also callback functions, the difference between the two is,
when you call this line
$("#next").click(next()); the function is executed immediately, and you are passing the result of the next function to the eventHandler of jQuery.
and in this case
$("#next").click(next); you are passing the function next to the EventHandler of jQuery.
Btw.: in the jQuery API Documentation (https://api.jquery.com/click/) it shows all parameters for the click function and the required types it states: "...handler Type: Function( Event eventObject ) A function to execute each time the event is triggered. ..."
try like this you will get your answer,
function next() {
//some code here
}
function previous() {
//some code here
}
$("#next").click(next);
$("#previous").click(previous);
working demo jsfiddle Example
What is going on there is a little bit obscured by the syntax of anonymous functions function() { ... }. What you are doing by that is passing a function, without calling it. And I want to explain how this works:
If you have a simple function
function next() { return 5 };
It will simply return the value 5, if you call it from somewhere:
a = next(); // value of a will be 5
But what you can do too, is to pass the whole function to a. This is possible, because functions in JavaScript are actually objects:
a = next;
b = a(); // value of b will be 5
If you look at the syntax, it shows you, that putting parentheses () at the end of a function invokes it, and returns the return value. While the naked string, without parentheses hands you the function itself.
So what is a callback now, and what does click() like to get as a parameter? A callback function is a function, that gets called later; we actually hand it over, to get called later. click() would like to get such a function as parameter, and it should be clear now, that we have to pass the function without parentheses, to enable click() to call it later, instead of just passing a 5 to it.
$("#next").click(next);
So how does then the initial syntax with the anonymous function work?
function() { next(); }
actually wraps your next() into another function, which is anonymous – because it does not have a name – but is working in the same way as a named function. You can even set a variable by it:
a = function() { next(); } // a will be the anonymous function that calls next()
But calling that function a() will return nothing, because the anonymous function does not return a value (To be exactly: every function call in JavaScript is returning at least undefined, but that's a technical detail).
It can even be called immediately by putting parenthesis at the end of it:
a = function() { return next(); }() // value of a will be 5
Adding the return there will make sure, the return value of next() will be passed through the anonymous function.
This should make clear why
$("#next").click(function(){ next(); });
is working, and why
$("#next").click(next());
is not, but
$("#next").click(next);
will be a good solution.
$("#next").click(next); would work. Notice parenthesis are not required as the function/callback handler should be passed as a parameter.

Can Someone Explain me the Callback functions?

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.

jQuery - Using anonymous function passed in as function parameter as jQuery callback function

This is best explained by a code example, so can anyone explain why (in technical terms) the anonymous function passed to test doesn't get called after the jQuery hide event?
UPDATE: Not that is really matters for this example what this is referring to, but for clarity lets say test function is in the global scope and this is an anchor element.
test(this, function() {
alert('Called by anonymous function!');
});
function test(object, callback) {
$(object).hide('slow', callback);
}
Changing:
$(object).hide('slow', callback);
To:
$(object).hide('slow', callback());
works. Is this because callback isn't a named function in the current context or global window object?
Your code should look more like this
test(this, function() {...});
You're not calling an anonymous function in your code, but I'm not sure what that syntax actually does
Check out this fiddle of a working example http://jsfiddle.net/L4NxD/2
Edit, made more edits to the fiddle to better duplicate original code. Use http://jsfiddle.net/L4NxD/1 and just http://jsfiddle.net/L4NxD/ to get earlier versions.
This is the correct way to do it.
http://jsfiddle.net/6dFm6/6/
Calling remove after the hide animation will remove the object and result in the animation callback not being called.
The reason it works in jsfiddle.net/6dFm6/1 is because the callback is executed at runtime and the value is passed and called during the callback event.
See these articles for varying level of clarity on what is returned by 'functionName()' as the callback. It appears 'undefined' is returned by the call, however the execution still happens at the correct time.
When to use () after a callback function name?
In JavaScript, does it make a difference if I call a function with parentheses?
Callback function - use of parentheses
do I need parenthesis when using a named function as an jquery ajax success callback
javascript syntax: function calls and using parenthesis

JavaScript: How to pass an anonymous function as a function parameter?

I would like to write a function that accepts an anonymous function as a parameter. For example:
run('param1', function(){
alert('execute this');
});
function run(param1, callback) {
//now execute the callback parameter as a function
}
How can I achieve something like this?
callback() would invoke it.
If you need to supply a context, do callback.apply(this, arguments). When you use .apply be aware of the current execution context, basically know what this will refer to, or your code will not work as expected if you are feeding a literal that references this inside it's function body.

Categories

Resources