0

I am experiencing very strange behavior in a function that performs an AJAX call to my server.

The code below is lifted from my jQuery script. The 2 functions shown below appear exactly in this order within my script. If you follow the alerts, they document the processing order of the overall script.

What is odd, and unexplained, and quite frankly problematic to my script's process is that the $.ajax() call does not get executed when I am needing it to. It gets executed last.

Is there something wrong with the coding of my script?

$(document).ready(function() {
  $(window).load(function() {

    $('#agentID').change(function() {
    alert('This alert displays on screen First');
      $.ajax({
        url: '/scripts/ajaxAgent.php',
        type: 'GET',
        dataType: 'html',
        data: 'lookup=' + $('#agentID').val(),
        success: function(data) {
          if (data == 1) {
    alert('Oddly and incorrectly, this alert displays on screen Third');
            $('.visibility').show();
            $('#resTypeID').closest('div').removeClass("optional");
            $('#resTypeID').closest('div').addClass("required");
          }
          else {
    alert('Oddly and incorrectly, this alert displays on screen Third');
            $('.visibility').hide();
            $('#resTypeID').closest('div').removeClass("required");
            $('#resTypeID').closest('div').addClass("optional");
          }
          resTypeVisibilityHandler = data; // this var is set to global at top of this script
        }, // end success
        error: function() {
          alert('An error occurred in processing.');
        } // end error
      }); // end .ajax()
    }); // end agentID .change()

    $('#agentID').focus();
    $(document).on('change', '.visibilityControl', function(event) {
    alert('This alert displays on screen Second');
    // ...
    }); // end .on('change') visibility control

  }); // end .load()
}); // end .ready()

@pep has the answer to my unique question. For some reason SO is blocking new answers or incorrect answers. Here is the solution:

"So instead, you could simply wrap all of your code that needs to be executed when the script completes into a function. Then, at the end of AJAX success, you can call that function and at that point the timing will be correct, as the code would execute third in your example as expected."

He's got it...that's the work around !

2014-12-12 @ 13:15 (GMT-5) petitioned request to the SO Lords to reopen this question so I can properly accept the correct answer.

Bart
  • 19,692
  • 7
  • 68
  • 77
H. Ferrence
  • 7,906
  • 31
  • 98
  • 161
  • 2
    A in AJAX stands for Asynchronous, which means that your AJAX HTTP request is fired, but only at some later point in the future when your server responds will the `success` function be called. This is why you're seeing it execute 3rd. – p e p Dec 12 '14 at 18:02
  • Ah, got it. Thanks @pep. Is there anyway to halt the script processing until the ajax completes? – H. Ferrence Dec 12 '14 at 18:03
  • @H.Ferrence You could use `async: false,` **BUT** you shouldn't! See that: http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – A. Wolff Dec 12 '14 at 18:04
  • @H.Ferrence You can use the `async: false` option to `$.ajax`. But this is generally considered a bad idea. You should learn to embrace asynchrony, and design your application with it in mind. – Barmar Dec 12 '14 at 18:04
  • 1
    Well, you wouldn't want to because whenever script is 'halted' or 'waiting', your browser will appear to be frozen as the thread that renders UI is shared with the thread that executes script. So instead, you could simply wrap all of your code that needs to be executed when the script completes into a function. Then, at the end of AJAX success, you can call that function and at that point the timing will be correct, as the code would execute third in your example as expected. – p e p Dec 12 '14 at 18:05
  • 1
    Ignore the suggestions to use `async:false` unless you are willing to fully sacrifice page responsiveness during the entire duration of your AJAX request. If your AJAX call for some reason takes 3 seconds to respond, your browser would appear frozen in that case. – p e p Dec 12 '14 at 18:06
  • Great suggestion @pep...if you document it as an answer then I will accept it. – H. Ferrence Dec 12 '14 at 18:08

2 Answers2

1

Ajax uses the asynchronous way of fetching data. Now this means once the request for the data is initiated the page continues running rest of the javascript (if available) and runs the promises of the ajax once the data is received. So it all depends on how much time it takes the data to return from the ajax URL. In every case the ajax promises would run last as the script in the browser runs almost instantaneously but it takes more time to get data from the server.

Anubhav
  • 7,138
  • 5
  • 21
  • 33
1

That is the expected behaviour. Javascript is single threaded. A function like Ajax takes some time to execute as the delay in between the request and response. If javascripts waits for the results to come, then it blocks the the single thread and any javascript code couldn't run until the response comes.

To get rid of this, javascripts uses asynchronous non-blocking event mechanism. Ajax is an asynchronous function. As AJAX call takes time for getting the results, You are passing a function to be executed after the response comes. Javascript doesn't wait until the request comes and js continues executing the code below the Ajax function until the response comes.. When the response comes js executes the function you send (callback) to the Ajax function. That's the reason for the delay of the third alert..

Sampath Liyanage
  • 4,776
  • 2
  • 28
  • 40