Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make javascript code execute *in order*

Tags:

Okay, so I appreciate that Javascript is not C# or PHP, but I keep coming back to an issue in Javascript - not with JS itself but my use of it.

I have a function:

function updateStatuses(){  showLoader() //show the 'loader.gif' in the UI  updateStatus('cron1'); //performs an ajax request to get the status of something updateStatus('cron2'); updateStatus('cron3'); updateStatus('cronEmail'); updateStatus('cronHourly'); updateStatus('cronDaily');  hideLoader(); //hide the 'loader.gif' in the UI  } 

Thing is, owing to Javascript's burning desire to jump ahead in the code, the loader never appears because the 'hideLoader' function runs straight after.

How can I fix this? Or in other words, how can I make a javascript function execute in the order I write it on the page...

like image 411
Ed. Avatar asked Apr 14 '10 13:04

Ed.


People also ask

Does JavaScript execute in order?

JavaScript is synchronous. This means that it will execute your code block by order after hoisting. Before the code executes, var and function declarations are “hoisted” to the top of their scope.

What is the execution order of the code?

Software has an order of execution. This is the program sequence, meaning the order in which your lines of code will be executed. Your key takeaways are: Software executes synchronously unless asynchronous features are used.

How program is executed in JavaScript?

The Execution Context contains the code that's currently running, and everything that aids in its execution. During the Execution Context run-time, the specific code gets parsed by a parser, the variables and functions are stored in memory, executable byte-code gets generated, and the code gets executed.


2 Answers

The problem occurs because AJAX is in its nature asynchronus. This means that the updateStatus() calls are indeed executed in order but returns immediatly and the JS interpreter reaches hideLoader() before any data is retreived from the AJAX requests.

You should perform the hideLoader() on an event where the AJAX calls are finished.

like image 145
anorm Avatar answered Oct 20 '22 12:10

anorm


You need to think of JavaScript as event based rather than procedural if you're doing AJAX programming. You have to wait until the first call completes before executing the second. The way to do that is to bind the second call to a callback that fires when the first is finished. Without knowing more about the inner workings of your AJAX library (hopefully you're using a library) I can't tell you how to do this, but it will probably look something like this:

showLoader();    updateStatus('cron1', function() {     updateStatus('cron2', function() {       updateStatus('cron3', function() {         updateStatus('cronEmail', function() {           updateStatus('cronHourly', function() {             updateStatus('cronDaily', funciton() { hideLoader(); })           })         })       })     })   }) }); 

The idea is, updateStatus takes its normal argument, plus a callback function to execute when it's finished. It's a reasonably common pattern to pass a function to run onComplete into a function which provides such a hook.

Update

If you're using jQuery, you can read up on $.ajax() here: http://api.jquery.com/jQuery.ajax/

Your code probably looks something like this:

function updateStatus(arg) {   // processing    $.ajax({      data : /* something */,      url  : /* something */   });    // processing } 

You can modify your functions to take a callback as their second parameter with something like this:

function updateStatus(arg, onComplete) {   $.ajax({     data : /* something */,     url  : /* something */,     complete : onComplete // called when AJAX transaction finishes   }); 

}

like image 31
meagar Avatar answered Oct 20 '22 13:10

meagar