Understanding Javascript callbacks - javascript

I am reading various tutorials on javascript with callbacks, but they are not clarifying a basic principle. What I understand is that when a function is called with a callback, this makes it possible to wait on execution of some code, and after that execute the callback function. So
// function definition
do_func(int num, callback)
{
Console.log(num);
..
..
callback();
}
//call the function
do_func(123, function(){
Console.log("Running callback");
});
So during execution of do_func, all lines of code are executed, and then callback() is executed. However if our function changed as
// function definition
do_func(int num, callback)
{
read file...
..
..
callback();
}
Then the callback would be called while the file is being read. So our purpose is defeated. What is happening here?
Thanks very much!

JavaScript itself is synchronous and single-threaded. You cannot write an asynchronous function.
What you can do is use some APIs provided by your environment (Node.js, Web browser) that allow you to schedule asynchronous tasks... timeouts, ajax, FileAPI to name a few.
An example using setTimeout (provided by the HTML Timing API):
window.setTimeout(function() {
console.log("World");
}, 1000);
console.log("Hello");
What is a simple example of an asynchronous javascript function?

do_func(int num, callback)
{
readFile(... , callback);
}
I'd expect that you're readFile function can also take a callback so you could just pass it along until the file has been read.

You are correct that in your example callback() would be called right away without waiting for the file to load. In JavaScript anytime something asynchronous is encountered you can generally listen for an event to know when to run the callback function.
Example loading an image:
var img = new Image();
img.addEventListener('load', callback); //add your listener first because if you ran the next line first it might load before your listener is setup
img.src = "fileondisk.jpg";

Related

Storing function call results for later referall

I've been trying to read as much as I can about javascript callbacks and jquery deferred objects but apparently things just aren't clicking for me. It seems to make a vague amount of sense when I read through it and practice examples, but when I try to apply it to my specific problem, I'm just hitting a wall. If anyone can understand what I'm trying to do and offer ideas, it would be much appreciated!
Here's some existing code:
$(document).ready(function() {
firstFunction();
secondFunction();
});
For the sake of keeping things simple here, I won't get into what firstFunction() and secondFunction() do, but suffice it to say that they both perform asynchronous work.
Here's my problem:
firstFunction() is dependent on the document being ready so needs to be inside $(document).ready(function() { }. secondFunction() isn't dependent on $(document).ready(function(), but should only execute after firstFunction has completed. I'm hoping to do all the computation for secondFunction() before the $(document).ready(function() { } block, but only execute it after firstFunction() has completed. This way firstFunction and secondFunction will execute in a more visually seamless manner. So basically, I'd like to do something like the following pseudo code:
var deferredSecondFunction = secondFunction().compute().defer(); //perform computation for secondFunction but defer execution
$(document).ready(function() {
firstFunction().done.execute(deferredSecondFunction().execute()); //finally execute secondFunction once firstFunction has completed.
});
Does anyone know if this is even possible? An important caveat is that I need to do this without the Javascript Promise object, since, for reasons outside the scope of this question, the webkit I'm working with is an old version. If anyone could help me understand this it would be appreciated!
The code shown uses a callback function and a self-invoking anonymous JavaScript function such has:
var calculatedObject;
(function(){
// Will be executed as soon as browser interprets it.
// write code here & save your calculations/operations
calculatedObject = { ... };
})();
function firstFunction(callback){
// Do stuff
callback();
}
function secondFunction(){
// Do more stuff
// Use your calculations saved in the calculated object.
}
$(document).ready(function(){
firstFunction(secondFunction);
});
This way the second function will only be called at the end of the first one.
you can use a callback..
function f1(){
//do some stuff
}
function f2(callback){
// do some async stuff
callback();
}
f2(f1);
this example passes one function to another function. the second function then calls the first whenever it's ready.

Javascript Callback functions vs just calling functions

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();
}

Asynchronicity in Javascript

I have a question about asynchronicity in Javascript. From what I've been able to read up on about is that Javascript only uses one thread but is able to handle events asynchronously.
I have the following code:
game.next();
this.autopilot();
Now, I need the function game.next to finish before the this.autopilot function is called. Does Javascript actually wait until game.next is finished or does it run this.autopilot istantly?
If it does, does a callback solve the problem?
The next function with a callback:
Game.prototype.next = function(callback) {
// Code
if(callback !== undefined) {
callback();
}
};
The calling function using that callback:
game.next(function() {
this.autopilot();
}.bind(this));
In your code, game.next() must return before this.autopilot() is called.
However, it is possible that game.next() starts an asynchronous process (e.g., an Ajax call) and returns before the process completes. If you want to defer execution of this.autopilot() until that process is complete, then you would need some sort of callback mechanism. game.next() would have to pass the callback function on to whatever asynchronous processing was taking place. (Executing the call-back just before returning—as you suggest in your question—would be wrong, as this would also happen before the asynchronous process completed.)
Yes, you can use a callback to make sure game.next() finishes before this.autopilot(). But there is a trick: you just cannot paste some callback after whatever code. Whether or not you need to implement a callback depends on whether game.next() function is asynchronous.
Example of a synchronous function that doesn't need a callback:
function next() {
Game.x += 1;
}
Example of an asynchronous function that needs a callback to preserve the execution order:
function next(callback) {
window.setTimeout(function() {
if(callback !== undefined) { /* etc. */ }
}, 0);
}

How does one use $.deferred properly with non-observable functions?

Let's say for example that I have two functions with random code inside and also that based on the user's system (slow, medium, or fast) there is no way to tell how long the two functions will take to complete, so the use of setTimeout is not practical when trying to fire function2 only after function1 is complete.
How can you use jQuery.deferred to make function2 fire only after function1 no matter what the time requirements are, and considering that both functions are 100% non-jQuery functions with no jQuery code inside them and therefore completely un-observable by jQuery? At the very most, the functions might include jQuery methods like .css() which do not have a time association and can run slower on old computers.
How do I assure that function2 is not executing at the same time as function1 if I call them like this:
function1(); function2();
using $.deferred? Any other answers besides those regarding $.deferred are also welcome!
ADDED March 20:
What if function1() is a lambda function where, depending on user input, the function may or may not have asynchronous calls and it is not possible to tell how many operations the function will do? It'd be a function where you wouldn't have any clue as to what would happen next, but no matter what, you'd still want function2 to execute only after everything from the lambda function (function1) is done, no matter how long it takes but as long as the asynchronous aspects are completed. How can this be achieved?
ADDED March 22:
So I guess the only way to do what I'm asking is to pass anonymous functions as callbacks to asynchromous functions that execute the callbacks after they are done, or to create event listeners that will do execute what you want when the event is finally triggered.
There's not really any way to just execute to asynchronous calls on two seperate lines and have them fire in order without manually constructing mechanisms (event handlers) within the frame containing the said functions to handle the actual execution of their actions.
A good example of these types of mechanisms would be jQuery's .queue() method and $.Defferred object.
The answers below along with reading up on jQuery's API on .queue()ing and using $.Deferred helped clarify this.
Tgr gave a great example below on how to create custom chainable functions using jQuery's $.Deferred object, and the custom functions themselves don't necessarily have to have any jQuery code inside them, which is exactly what I was looking for.
function first(deferred) {
// do stuff
deferred.resolve();
}
function second() {
// do stuff
}
$.Deferred(first).then(second);
But as Tomalak pointed out, this is unnecessary, unless you do something very tricky in first (like utilising web workers).
Update:
The basic idea is that whenever you do something that is not immediate, you create a Deferred object, and return that. (jQuery's AJAX calls already do this.) You can then use Deferred.then to delay follow-up operations.
function first() {
var deferred = $.Deferred();
var callback = function() {
deferred.resolve();
}
// do immediate stuff
someAsyncOperation(callback);
return deferred.promise(); // turns the Deferred into a Promise, which
// means that resolve() will not be accessible
}
function second() {
// do stuff
}
first().then(second); // or: $.when(first).then(second)
If second is also an asynchronous operation, you can use $.when's merging capabilities:
function second() {
var anotherDeferred = $.Deferred();
// do stuff with anotherDeferred
return anotherDeferred.promise();
}
$.when(first(), second()).then(third); // third will run at the moment when
// both first and second are done
JavaScript itself is not asynchronous. It is single-threaded, synchronous.
function1();
function2();
will execute one after another unless they contain asynchronous calls. In that case, there will always be a callback you can pass (like onSuccess for XmlHttpRequest). Place the second function there.
To say the truth, they strictly execute one after another even if they contain asynchronous bits. It's just that the asynchronous bits might not yet be finished when the rest of the function is.
EDIT Your jsFiddle example, fixed (see it):
function foo() {
$('#foo')
.html('<span>foo1</span>')
.animate(
{ /* properties */
left: '100px'
},
360, /* duration */
'swing', /* easing */
function () { /* "complete" callback */
$('#foo').append('<span>foo2</span>');
bar();
}
);
}
As I said. There will always be a callback you can pass.

callback function meaning

What is the meaning of callback function in javascript.
JavaScript's "callback" is function object that can be passed to some other function (like a function pointer or a delegate function), and then called when the function completes, or when there is a need to do so. For example, you can have one main function to which you can pass a function that it will call...
Main function can look like this:
function mainFunc(callBack)
{
alert("After you click ok, I'll call your callBack");
//Now lets call the CallBack function
callBack();
}
You will call it like this:
mainFunc(function(){alert("LALALALALALA ITS CALLBACK!");}
Or:
function thisIsCallback()
{
alert("LALALALALALA ITS CALLBACK!");
}
mainFunc(thisIsCallback);
This is extensively used in javascript libraries. For example jQuery's animation() function can be passed a function like this to be called when the animation ends.
Passing callback function to some other function doesn't guarantee that it will be called. Executing a callback call (calBack()) totally depends on that function's implementation.
Even the name "call-back" is self-explanatory... =)
It's just a name for a function that should be called back after something.
It's often used with XMLHttpRequest:
var x = new XMLHttpRequest();
x.onreadystatechange = function(){
if(x.readyState == 4){
callbackfunction(x.responseText);
}
}
x.open('get', 'http://example.com/', true);
x.send(null);
callbackfunction is just a plain function, in this case:
function callbackfunction(text){
alert("I received: " + text);
}
Besides just being a function, a callback function is an enabler for asynchronous application design.
Instead of calling a function and waiting for the return value(s), potentially locking up the thread or the entire PC or UI on single threaded systems while you wait, with the async pattern you call a function, it returns before finishing, and then you can exit your code (return back to the calling OS, idle state, run loop, whatever...). Then later, the OS or asynchronous function calls your code back. The code you want it to call back is usually encapsulated in something called a "callback function". There are other uses, but this is a common one in OOP UI frameworks.
With the latest iOS 4.x, you can also use nameless "blocks" for the callback. But languages that don't have blocks (or anon closures under another name) use functions for function callbacks.
You can simply use the below statement onClick event of back button:
OnClick="javascript:history.go(-1)"
it will work to take you back to your previous page which you had visited recently.

Categories