Question

I'm doing an AJAX call (regular JS) and, if it takes more than, say, 500 milliseconds, I'd like to put up my "Please Wait" box.

Normally, if I want to put up the PW box immediately, I'd do:

// show semi-transparent grey screen to block access to everything underneath
divGreyCoverAllNode.style.display = 'inline';
// show PW box. Prior to these lines, both coverall and PW were display=none
divPleaseWaitNode.style.display = 'inline';

// now do the AJAX and follow-up inside a zero timer; the timer is necessary to
// make the system pause to display the screen changes we previously invoked 

setTimeout( function() {
        // do my ajax call here, then after the call...
        // take down the PW stuff
        divPleaseWaitNode.style.display = 'none';
        divGreyCoverAllNode.style.display = 'none';
    },
    0
);

Like I stated above, what I'd like to do is have the PW displayed only if AJAX doesn't finish in, say, 500 milliseconds. Ideally it would be something like:

// set a timer to display PW in 500 milliseconds
myTimeEvent = setTimeout( function() {
        divGreyCoverAllNode.style.display = 'inline';
        divPleaseWaitNode.style.display = 'inline';
    },
    500
);

// do my ajax call here, then after the call...
clearTimeout(myTimeEvent);
// take down the PW stuff, in case it was displayed
divPleaseWaitNode.style.display = 'none';
divGreyCoverAllNode.style.display = 'none';

But I can't seem to get the system to pause and display the PW when AJAX is taking its time. I've tried surrounding the AJAX-and-follow-up block in a zero timer, but no deal.

Any suggestions?

EDIT: Important fact: This is not an asynch ajax call. It's an unusual situation that requires everything to wait on the ajax result.

Was it helpful?

Solution

Given that you are making a synchronous XHR call, you can't. That's the nature of synchronouseverything stops until the call completes. When you use a synchronous XHR request, not only is the JavaScript event loop stopped, you actually freeze the entire browser UI (in IE and Firefox < 3).

That said, you're doing it wrong. 8.4% of reported IE9 hangs last month were due to synchronous XHR. There really is no such thing as ‘an unusual situation that requires use of synchronous XHR requests.’ Make your request, then act on the data you get in the callback function.

Instead of something like:

// Do stuff, then when you need a request:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();
// Do more stuff
alert(xhr.responseText);

You need:

// AJAX helper
function req(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) callback(xhr);
  }
}


// Your code.  Do stuff, then when you need an AJAX request:
req(url, function(xhr) {
  // Do more stuff
  alert(xhr.responseText);
});

Obviously this needs refined, but this illustrates the proper way to make an AJAX request.

OTHER TIPS

It shouldn't come after the ajax call, it should come inside the callback function. AJAX requests are asynchronous with the rest of the code, you should preform actions you want upon completion inside the callback part of your request.

take a look at BlockUi. If that doesn't look like it will work for you, you could try using

$(document).ajaxStop(DoSomething()); 

Take a Look at jQuery Timeout

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top