We help IT Professionals succeed at work.

Why isn't this javascript callback behaving as I would expect?

James Froggatt
on
I am just learning about Javascript callback functions so am playing with simple code.

<script>
  function doTwoFunctions(callback){
    setTimeout( function(){console.log("First Function")}, 500 );
    callback();
  }

  function secondFunction(){
    console.log("Second Function");
  }

  doTwoFunctions(secondFunction);
</script>

Open in new window


With this code, I would expect the console to show;

First Function
Second Function

but it isn't. It's showing

Second Function
First Function

Clearly my callback isn't working.

What have I done wrong please?

Thank you
James
Comment
Watch Question

leakim971Multitechnician
Distinguished Expert 2019

Commented:
<script>
  function doTwoFunctions(runMeNow){
    setTimeout(runMeAfter500ms, 500 );
    runMeNow();
  }

  function runMeASAP(){
    console.log("Second Function");
  }
  function runMeAfter500ms(){
    console.log("First Function");
  }
  doTwoFunctions(runMeASAP);
</script>

Open in new window

Author

Commented:
Thank you for that leakim971.

Can you explain why my version isn't working?

Thank you

Author

Commented:
... in other words, why is

setTimeout( function(){console.log("First Function")}, 500 );

not behaving like your

setTimeout(runMeAfter500ms, 500 ); (where you are calling an external function)
leakim971Multitechnician
Distinguished Expert 2019

Commented:
because this line :
setTimeout(runMeAfter500ms, 500 );
is not a STOP.
I mean the next line doesn't wait 500ms before running

Time in ms |  code
00001        |  setTimeout(runMeAfter500ms, 500 );
00001        |  runMeNow();
00001        |  }
later
00500        |  runMeAfter500ms();

Author

Commented:
BTW, your code seems to give output like mine

Second Function
First Function

So doesn't seem to be correct either?
leakim971Multitechnician
Distinguished Expert 2019

Commented:
So doesn't seem to be correct either?

yes, it not a fixed version
just different names trying to show you what is happening
leakim971Multitechnician
Distinguished Expert 2019

Commented:
<script>
  function doTwoFunctions(runMeNow){
    setTimeout(function() {
         runMeAfter500ms();
         runMeNow();
   }, 500 );
  }

  function runMeASAP(){
    console.log("Second Function");
  }
  function runMeAfter500ms(){
    console.log("First Function");
  }
  doTwoFunctions(runMeASAP);
</script>

Open in new window


500ms.JPG

Author

Commented:
Can I ask this. I thought the idea of a callback was to effectively make sure functions are executed in order. So for example, if I do an AJAX call, ensuring that another function (that depends on that call), only triggers after the ajax call is completed.

I understand it as a 'timing' thing, to ensure functions are only executed when the necessary data is present for them to work (e.g. an ajax call).

So I'm confused as to why my code in my question doesn't work.

By using the timeout in my original code, I'm trying to simulate for example an Ajax call (i.e. something dependent on time passing before the next function is called), but it doesn't.

Why is that?

Thank you
James

Author

Commented:
... I'm just trying to get a full understanding of CallBacks .... btw... your code above works fine....I'm hoping you can see where my confusion must be and elighten me. Thanks
leakim971Multitechnician
Distinguished Expert 2019

Commented:
I'm confused as to why my code in my question doesn't work
in your code
setTimeout( function(){console.log("First Function")}, 500 );
    callback()

Open in new window


callback run IMMEDIATELY after setTimeout
but function(){console.log("First Function")} run after 500ms, this is the goal of setTimeout

By using the timeout in my original code, I'm trying to simulate for example an Ajax call
I got this and this is what I do to simulate Ajax call too but this way :

<script>
  function doTwoFunctions(callback){
    console.log("First Function");
    callback();
  }

  function secondFunction(){
    console.log("Second Function");
  }

 setTimeout(doTwoFunctions, 500); // doTwoFunctions is your callback 
 
</script>

Open in new window

Author

Commented:
I think I álmost get this.

With your code above, I''m getting the console error

js.html:4 Uncaught TypeError: callback is not a function
    at doTwoFunctions (js.html:4)
doTwoFunctions @ js.html:4
setTimeout (async)
(anonymous) @ js.html:11


please help, I want to get your code working so I can understand it.

Thank you

Author

Commented:
Is using the following the correct way to execute you code?

setTimeout(doTwoFunctions(secondFunction), 500);
Multitechnician
Distinguished Expert 2019
Commented:
<script>
  function callback(){
    console.log("First Function");
    secondFunction();
  }

  function secondFunction(){
    console.log("Second Function");
  }

 setTimeout(callback, 500); // doTwoFunctions is your callback 
 
</script>

Open in new window

Author

Commented:
Give me a moment, I'm trying to let the above sink in.... I think I'm struggling to see a callback at all now.... Be patient with me.

Author

Commented:
Thankyou for your help. I have learnt a great deal about callbacks in this discussion.
leakim971Multitechnician
Distinguished Expert 2019

Commented:
you welcome
have fun!