Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get a browser window to update while it is in a Javascript loop?

I have an Ajax call that currently needs to be synchronous. However, while this Ajax call is executing, the browser interface freezes, until the call returns. In cases of timeout, this can freeze the browser for a significant period of time.

Is there any way to get the browser (any browser) to refresh the user interface, but not execute any Javascript? Ideally it would be some command like window.update(), which would let the user interface thread refresh.

If this would be possible, then I could replace the synchronous AJAX call with something like:

obj = do_async_ajax_call();
while (!obj.hasReturned()) {
  window.update();
}
// synchronous call can resume

The reason that I can't use setTimeout, or resume a function in the callback, is that the execution flow cannot be interrupted: (there are far too many state variables that all depend on each other, and the long_function() flow would otherwise have to be resumed somehow):

function long_function() {
   // lots of code, reads/writes variable 'a', 'b', ...
   if (sync_call_is_true()) {
     // lots of code, reads/writes variable 'a', 'b', ...
   } else {
     // lots of code, reads/writes variable 'a', 'b', ...
   }
   // lots of code, reads/writes variable 'a', 'b', ...
   return calculated_value;
}
like image 576
jevon Avatar asked Feb 03 '10 00:02

jevon


1 Answers

You need to replace your synchronous request with an asynchronous request and use a callback. An oversimplified example would be:

obj = do_async_ajax_call(function (data, success)
{
    if (success) 
    {  
        // continue...  
    } 
}); 

function do_async_ajax_call(callback)
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "http://mysite.com", true);
    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState == 4 && xhr.status == 200)
            callback(xhr.responseXML, true);
        else if (xhr.readyState == 4)
            callback(null, false);
    }
    xhr.send();
}

This way you're passing an anonymous function as a parameter to the ajax requesting function. When the ajax is complete, the function that was passed is called with the responseXML passed to it. In the meantime, the browser has been free to do it's usual thing until the call completes. From here, the rest of your code continues.

like image 109
Andy E Avatar answered Nov 15 '22 11:11

Andy E