Learning javascript and wanted to get more clarity regarding callbacks.
In the following code snippet,
function do_a( callback ){
// if callback exist execute it
callback && callback();
}
function do_b(){
console.log( 'do_b executed' );
}
//one way
do_a( function(){
do_b();
});
//other way
do_a(do_b);
Is there a difference between the two ways the do_a() is called. One passes a pointer to the do_b function, the other passes a function which executes the do_b function. All the examples i've seen use the first way. Is that more preferred style wise?
The first way just creates an extra anonymous function that calls the second function. This is useful if you want to perform actions before or after calling the callback, e.g.
do_a( function(){
console.log("I'm going to call the second function...");
do_b();
console.log("Second function is done.");
});
Otherwise, I can't see any point in this extra function and the second way is better.
you don't have to pass it as an argument. Directly call it.
function abc(){
a = "function abc";
console.log(a);
cde();
console.log(a);
}
function cde(){
a="function cde";
}
abc();
Related
I have a function with a variable called callback
function test(callback){
// Some code
callback;
}
When I call this function I used to insert a one liner into callback
eg. test($('#elem').hide());
Now I want to put multiple lines in here as the callback. I tried this but it does not appear to work.
var resetc = function(){
$('.access').removeClass('viz');
window.setTimeout(function(){
$('.access').find('.input.wheel').removeClass('viz');
$('.access').find('input').removeAttr('disabled');
},1000);
}
test(resetc);
As you are passing the function reference. You can use the callback variable to execute the function which it is referring. like
function test(callback) {
// Some code
callback();
}
You statement test($('#elem').hide()); is having no effect as you are passing the output of $('#elem').hide() to your method test and statement callback; actually is not performing anything.
You need to change your function call for test($('#elem').hide()); with
test(function() {
$('#elem').hide();
});
Your initial code doesn't do what you think. To call a callback, you need to put () after it:
function test(callback) {
// some code
callback();
}
If you fix that, test(resetc); will do what you want.
The reason you didn't notice this in your first test is because when you write
test($('#elem').hide());
you're executing $('#elem').hide() before calling test, it's not being done when test runs the callback. You need to pass a function to defer the execution until the callback is called:
test(function() {
$('#elem').hide();
});
So i don't really understand the point of "callback".
Here is an example of callback:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name,myfunc){
alert("Hello");
myfunc;
}
sayHello("Max",saySeeYou());
Whats the point of passing in a function when you can just call the function? like this code does the exact same:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name){
alert("Hello");
saySeeYou();
}
sayHello("Max");
Whats the point of passing in a function when you can just call the function?
Usually, callbacks Javascript are used in Javascript for code that you want to run in the future. The simplest example is setTimeout: if you call the callback now then the code runs immedieately instead of after 500 ms.
//prints with a delay
console.log("Hello");
setTimeout(function(){
console.log("Bye");
}, 500);
//no delay this time
console.log("Hello");
console.log("Bye");
Of course, it would be really neat if we could write something along the lines of
//fake Javascript:
console.log("Hello");
wait(500);
console.log("Bye");
But sadly Javascript doesnt let you do that. Javascript is strictly single-threaded so the only way to code the wait function would be to pause the execution of any scripts in the page for 500 ms, which would "freeze" things in an unresponsive state. Because of this, operations that take a long time to complete, like timeouts or AJAX requests usually use callbacks to signal when they are done instead of blocking execution and then returning when done.
By the way, when passing callbacks you should only pass the function name. If you add the parenthesis you are instead calling the function and passing its return value instead:
//When you write
foo(10, mycallback());
//You are actually doing
var res = mycallback();
foo(10, res);
//which will run things in the wrong order
Your code is not correct as Felix Kling already pointed out. Besides this, passing a function instead of calling one directly allows you to insert different behavior, your code is more decoupled and flexible. Here an example:
function sayBye(){
alert("Bye!");
}
function saySeeYou(){
alert("See you!");
}
function sayHello(name,myfunc){
alert("Hello");
if (myfunc) {
myfunc();
}
}
sayHello("Max",saySeeYou);
// I'm inserting a different behavior. Now instead of displayng "See you!"
// will show "Bye!".
sayHello("Max",sayBye);
You are doing it wrong, you should do like bellow
Don't call the function just pass the function as callback
use this
sayHello("Max",saySeeYou); //here the second parameter is function
instead of
sayHello("Max",saySeeYou());//This will put the result of saySeeYou as second parameter
in say hello call the functiom
function sayHello(name,myfunc){
console.log("Hello");
myfunc();
}
I have a function that stores several values from a HTML form, and that must work individually in order to store that info in any situation I need (ie before inserting on DB, or before udating info on DB...)
I need to be able to tell the system to execute this function ('storeValues'),and then execute any other (could be 'createNewClass', 'updateExistingClass'... whatever).
How can I sequence this? I tried here to store values first and, WHEN DONE, execute another function aleting about a value, but it says "storeValues() is not defined", and it is defined:
$('.tableClassHeader').on('click', '.createClass', function(){
storeValues().promise().done(function(){
createNewClass();
});
});
function storeValues(){
cl_year = $('.newClassForm').find('select[name=cl_year]').val();
cl_course = $('.newClassForm').find('select[name=cl_course]').val();
}
function createNewClass(){
alert(cl_year);}
I mean that storeValues function SHOULD BE a separate function with the possibility of being called from any other place, I know this problem could be solved by executing "createNewClass" from the "storeValues" function, but there will be times that I need to execute "updateClass" after "storeValues", not "createNewClass"
You can use a callback like this, if your storeValues is not synchronous like in your example:
$('.tableClassHeader').on('click', '.createClass', function(){
storeValues(createNewClass);
});
function storeValues(callback){
cl_year = $('.newClassForm').find('select[name=cl_year]').val();
cl_course = $('.newClassForm').find('select[name=cl_course]').val();
callback();
}
function createNewClass(){
alert(cl_year);
}
If it is synchronous, just calling createNewClass after storeValues is enough.
What this does is:
offers you the ability to pass a function of choice to the storeValues
inside storeValues it calls the callback function passed as parameter
If you need to execute your function with a different scope you can use call or apply.
Another way to do this, without callbacks would be using
http://api.jquery.com/promise/
http://api.jquery.com/jQuery.when/
http://api.jquery.com/deferred.promise/
Example as seen here http://jsfiddle.net/47fXF/1/ :
$('.tableClassHeader').on('click', '.createClass', function(){
$.when(storeValues()).then(createNewClass);
});
function storeValues(){
var dfd = new jQuery.Deferred();
setTimeout(function(){
console.log('storing values');
cl_year = $('.newClassForm').find('select[name=cl_year]').val();
cl_course = $('.newClassForm').find('select[name=cl_course]').val();
dfd.resolve();
}, 1000);
return dfd.promise();
}
function createNewClass(){
alert("trololo");
}
Added the setTimeout to simulate asynchronicity.
If your storeValues is making only one ajax request using jQuery, then you can return it directly as shown in the API documentation.
Also make sure to call resolve(), reject() appropriately.
Call like this . it first call the storeValues after executes the createNewClass function
$('.tableClassHeader').on('click', '.createClass', function(){
storeValues(function() {
createNewClass();
});
});
function storeValues(callback){
cl_year = $('.newClassForm').find('select[name=cl_year]').val();
cl_course = $('.newClassForm').find('select[name=cl_course]').val();
callback();
}
I want to save all sections, made updates to questions with IDs for the just saved sections, then save the questions, and then if that is successful fire a function nextPage that redirects the page. I'm trying to confirm this is correct. It seems to act funny if I don't have the anonymous function wrapped around saveAllQuestions.
saveAllSections(function () {saveAllQuestions(nextPage)});
Update:
On the success of saveAllSections it does the following:
if (typeof(callback) == 'function')
callback();
On the success of saveAllQuestions it does the following:
if (questionValuesToSave.length>0) {
saveAllQuestionValues(questionValuesToSave, callback);
}
else {
// once its done hide AJAX saving modal
hideModal();
if (typeof(callback) == 'function')
callback();
}
On the success of saveAllQuestionValues (assuming there are some) it does the following:
if (typeof(callback) == 'function')
callback();
Yes that is a generally correct syntax for a callback, though its hard to know for sure without seeing more code.
The following code
saveAllSections(saveAllQuestions(nextPage));
would fail because saveAllQuestions(nextPage) is the syntax to execute a function, rather than define it. So it will execute that immediately and pass the result to saveAllSections, which will try to use it as the callback. Since this is likely not a function, and almost definitely not the function you want to pass you will get strange behavior, most likely an error.
Wrapping this in an anonymous function means that you're passing a function to saveAllSections, which does not execute until it is called by the outer function or as a callback.
UPDATE:
Looks like saveAllQuestions is also async based on your description, so executing it immediately will definitely not work correctly. The anonymous function wrapper is a completely acceptable solution if you need to pass a param.
If you didn't, you could just use
saveAllSections(saveAllQuestions)
The reason you need to wrap saveAllQuestions in an anonymous function is because otherwise saveAllQuestions gets executed right away, and its return value gets passed as the callback to saveAllSections.
If you wrap saveAllQuestions in an anonymous function, you prevent saveAllQuestions from executing right away.
In javascript, you can pass a function as an argument. This allows for simpler code and asynchronous callbacks. In your attempt, you don't pass a function in. You execute a function, so the result of saveAllQuestions(nextPage) is passed into the function, not the function saveAllQuestions.
Hopefully this example helps.
function add(a,b) {
return a+b;
}
function mul(a,b) {
return a*b;
}
function doMath(num1, num2, op) {
return op(num1, num2);
}
document.write( doMath(4,5, add) ); // 9
document.write( doMath(4,5, function (n1,n2) {return n1+n2;}) ); // 9
document.write( doMath(2,5, mul) ); // 10
document.write( doMath(2,5, function (n1,n2) {return n1*n2;}) ); // 10
document.write( doMath( doMath(1,3, add) , 4, mul) ); // 16
I have a javascript which I didn't write but I need to use it ..
function function1()
... body..
and at the end
I have this
'callback': 'getListCallback'
}
What does this callback mean and getListCallback = function(obj) is another function, does this mean that results from function1 are returned to function getListCallback?
Tnx
A callback function is a function that is going to be called later, usually when some event occurs. For example, when adding an event listener:
function callback(){
alert("click");
}
document.body.addEventListener("click", callback, true);
In many cases you pass the callback function as an anonymous function:
setTimeout(function(){alert("It's been 1 second");}, 1000);
The code getListCallback = function1(obj); will not call getListCallback with the results of function1(obj). It will store whatever function1(obj) returns into getListCallback. If function1 returns a function, then you can call that function later, like so:
function function1(obj){
return function(){
alert("getListCallback was called. obj = "+obj);
}
}
getListCallback = function1(1);
getListCallback();
Yes, it should mean that
normally a callback function means a function which will call after current function execution finished.
This
getListCallback = function(obj){// do something} is like assigning this "function(obj){//....}" to a variable which can use in any place where you need to use that function.