Search code examples
javascriptjqueryajaxexecution

Is there a way to enforce javascript code is executed before launching a synchronous ajax call


I don't really know what i'm doing wrong here. I got some javascript (with jQuery) that go like this:

function myFunc(){
    $('.wait').addClass('waiting');
    console.log('wait');
    var r = $.ajax({type: "GET", url: "my_URL", async: false}).responseText;
    $('.wait').removeClass('waiting');
    console.log('stop wait');
    return r;
}

My problem is that the class "waiting" is not added while doing this call... What I mean is that when I call my function, I got a div that is supposed to be appear at the beginning and then be remove after but it doesn't show up. Everything seem to be proceeding accordingly. I got the result of my ajax call, when I tried to execute it without the

$('.wait').removeClass('waiting');

My div show up but only after I got the ajax response... I tried to time the request and it take approximately 2 second... so I don't really know why this is happening.

Could it be related to the synchronous ajax call? Since JavaScript is a procedural language, I thought that the addition of the class should be done before logging into the console and before starting the ajax call, but I got all the modification after I got the response (even in the JavaScript console, everything append after the ajax call).

Any help would be really nice!


Solution

  • Nothing happens in the browser while the function is running, so you need to use asynchronous code so that the browser can update the element. You can use the setTimeout method to run rest of the code after the browser has had a chance to update.

    As the code is asynchronous you can't return the value from the function, as the function exists before the AJAX call is made. Use a callback function to get the value:

    function myFunc(callback){
      $('.wait').addClass('waiting');
      window.setTimeout(function(){
        var r = $.ajax({type: "GET", url: "my_URL", async: false}).responseText;
        $('.wait').removeClass('waiting');
        callback(r);
      }, 0);
    }
    

    As you have to use asynchronous code to update the element, you can just as well make the AJAX call asynchronous, that keeps the browser from being unresponsive during the request:

    function myFunc(callback){
      $('.wait').addClass('waiting');
      $.ajax({type: "GET", url: "my_URL", success: function(data){
        $('.wait').removeClass('waiting');
        callback(data);
      }});
    }