user3425506
user3425506

Reputation: 1437

Javascript: what is a callback?

In this article which I was referred to the following statement is made:

Callbacks are a way to make sure certain code doesn’t execute until other code has already finished execution.

The article then goes on to illustrate this with an example:

function doHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}

doHomework('math', function() {
  alert('Finished my homework');

After this the articles states:

As you’ll see, if you type the above code into your console you will get two alerts back to back: Your ‘starting homework’ alert, followed by your ‘finished homework’ alert.

The implication seems to be that by using a callback the desired order of code execution has been ensured. That is you start your homework before you finish it. However, I feel I may have misunderstood the whole point of the article and therefore still do not understand callbacks and asynchronous code because when I slow down the first part of the doHomework function using setTimeout() the code executes (or at least returns) in the opposite order:

function doHomework(subject, callback) {

  setTimeout(function(){
      console.log(`Starting my ${subject} homework.`);
  }, 500); 

  callback();
}

doHomework('math', function() {
  console.log('Finished my homework');
});

The result I get from that is:

steve@Dell ~/my-app $ node app.js 
Finished my homework
Starting my math homework.
});

I am using node here (hence console.log() replaces alert()) but I do not think that is relevant.

It seems to me I have missed something quite fundamental and need to try and access what it is that I am trying to understand before I then try and understand it.

Any assistance on this journey would be greatly appreciated.

After getting great feedback I think the homework analogy was not helpful so I am now using the first code example in the article I referenced. The article gives this code:

function first(){
  // Simulate a code delay
  setTimeout( function(){
    console.log(1);
  }, 500 );
}

function second(){
  console.log(2);
}

first();
second();

The above returns 2 then 1 in the console.

I tried (without success) to reverse the return order to 1 then 2 with this:

function first(callback){
    setTimeout(function(){
        console.log(1);
    }, 500);
    callback();
}
function second(){
    console.log(2);
}
first(second);

The answer I got from Cleared (before it was edited) was to put the callback() inside the setTimeout() function. He used the homework example but here it is with this example:

function first(callback){
    setTimeout(function(){
        console.log(1);
        callback();
    }, 500);
}

function second(){
    console.log(2);
}

first(second);

I think that is closer to what I am imagining the article was getting at. It seems to make sense although I guess the precise context of what you are doing and what you want to happen determine what is right or wrong.

Upvotes: 2

Views: 843

Answers (5)

saifulmasud
saifulmasud

Reputation: 91

Example: 1

  
    normalFunc(callbackFunc)  

    function callbackFunc() {
      console.log('I am callback function')
    }

    function normalFunc(callbackParam) {
      console.log('I am normal function')
      callbackParam()
    }
  

Example: 2

  
    normalFunc(callbackFunc1, callbackFunc2)  

    function callbackFunc1() {
      console.log('I am callback function1')
    }

    function callbackFunc2() {
      console.log('I am callback function2')
    }

    function normalFunc(callbackParam1, callbackParam2) {
      callbackParam2()
      console.log('I am normal function')
      callbackParam1()
    }
  

Output:
I am callback function2, I am normal function, I am callback function1

I found an excellent article on this: https://masudsaiful.github.io/javascript-async-await-step-by-step-tutorial

Upvotes: 0

Higanbana
Higanbana

Reputation: 499

What exactly is callback?

Callback meaning function-in-function like recursive.

Let me give you an example:

Every day we eating then sleeping. But in JS code, JS is an impatient language unlike PHP. This is the example code:

// Consuming 3s to eating(just an example, not really 3s)
function eating() {
    setTimeout(function() {
        console.log('Eating...');
    }, 3000);
}

// Then go to sleep
function sleep() {
    console.log('Z..Z..Z');
}

eating();
sleep();

But you sleep immediately after...(When we run the code it runs the sleep first then eating())

To assure that everything works in order, meaning you only go to bed when done eating. So we need the eating() to tell when it's done to start the sleep():

// Consuming 3s to eating(just an example, not really 3s)
function eating(callback) {
    setTimeout(function() {
        console.log('Eating...');
        callback() // the function which will be proceeded after "Eating..."
    }, 3000);
}

// Then go to sleep
function sleep() {
    console.log('Z..Z..Z');
}

// call the function
eating(function() {
    sleep();
});

Yeah! Right now I think you can use callback in your code!

Where you can see callback?

You can see it in every JQuery code:

$("#hide").click(function(){ //the click() function call the function inside it which is callback
  $("p").hide();
});

$("#show").click(function(){
  $("p").show();
});

Upvotes: 2

Cleared
Cleared

Reputation: 2580

In general, the call to the callback is not at the end of the function, but rather after you have done the important things.

So if I understand your question, the doHomework-function should start doing homework (which takes time, in this case 500ms), and then the homework is finished. So the important things in your case is the console.log('Starting my ${subject} homework.'); which "takes 500ms" (since this is the time you need to do the homework).

Therefore, you should put the call to the callback right after console.log('Starting my ${subject} homework.');, i.e.

function doHomework(subject, callback) {

  setTimeout(function(){
      console.log(`Starting my ${subject} homework.`);
      callback();
  }, 500); 
}

doHomework('math', function() {
  console.log('Finished my homework');
});

Upvotes: 6

JestaBlunt
JestaBlunt

Reputation: 173

Callbacks in Javascript are used in asynchronous programming, where you can't ensure that the code above is running before the code below, like loading files from a server asyncronous.

The problem is, that with normal sequential programming, you can not ensure, that the data you fetch is fully loaded when the programm is running (i.e. if you run the script, one time the variable could be setted, another time it could be undefined, cause async task is still running), so you set a callback function, which gets connected to different states, ie. success or error on ajax call. The difference to normal programming flow is, your programm does not stop till it has loaded the data (or in your case, the timeout doesnt pause your program, the code afterwards is computed and the timeout can run of anytime, if you dont use a fix value).

So, to ensure that your code will run when the needed logic finishes, you have to pass a callback function, which is executed when the needed state is fulfilled (i.e. success/error on loading tasks, or a timeout is "finished".

The homework example IMO isnt the best sample, cause it doesnt touch the real use cases, as it always "waits" 500ms.

In your example the problem is, your "callback" is out of the "asyncronous" part of code, so its executed directly after starting the timeout, even if the timeout still is "running". Maybe your thinking of SetTimeout is the problem, in my javascript beginnings I thought its more like "pause for 500ms", but its "execute the scoped code after waiting for 500ms out of the normal code flow"

Here are some more informations, I can recommend the whole page, even if your not javascript noob ;) https://javascript.info/callbacks

Upvotes: 2

Quentin
Quentin

Reputation: 943142

Generally, you would call the callback function when you are finished doing whatever it is you are doing.

So you have the code inside and outside your setTimeout function backwards.

function doHomework(subject, callback) {
    console.log(`Starting my ${subject} homework.`);
    setTimeout(function(){
        console.log(`Finished my ${subject} homework.`);
        callback();
    }, 500); 
}

Upvotes: 3

Related Questions