Mateus Pires
Mateus Pires

Reputation: 983

Javascript get request is blocking the ui

Consider the following:

HTML:

...
<button id="get">Get</button>
<div id="result"></div>
...

JavaScript:

$('#get').on('click', function()
{
    var result = httpGet(getUrl() + 'query.php');
    document.getElementById('result').innerHTML = result;
});

function httpGet(theUrl)
{
    var xmlHttp = new XMLHttpRequest();

    xmlHttp.open('GET', theUrl, false);
    xmlHttp.send(null);

    return xmlHttp.responseText;
}

function getUrl()
{
    return window.location.href.substring(0, (window.location.href.lastIndexOf('/')) + 1);
}

PHP (query.php):

// Make database query and return the result.

So... When I click button get, it calls httpGet() and make a request to query.php, that make a database query and return the result, which is asigned to div result.

The problem is, until it get the result from the server, that is a slow process, the ui is blocked. How can I solve it?

Upvotes: 0

Views: 1964

Answers (2)

nbrooks
nbrooks

Reputation: 18233

You are making the request synchronously by passing false as the third parameter to the XmlHttpRequest's open method. By making that true the request will be asynchronous, and will not block.

However, that means you cannot wait for and return the result as you are doing currently. You will have to instead implement a callback pattern. This means that you define a function to be called once the AJAX request has completed, so that the main thread of your application does not have to wait for the result to move on.

Since you're using jQuery, you can take advantage of its simplified AJAX methods:

$('#get').on('click', function()
{
    $.get(getUrl() + 'query.php', function(result) {
        $('#result').html(result);
    });
});

function getUrl()
{
    return window.location.href.replace(/(.*\/)[^/]*$/, "$1");
}

Also see the jQuery documentation for the ID selector, and the html method—incorporated above.

Upvotes: 2

Pablo Matias Gomez
Pablo Matias Gomez

Reputation: 6813

The last parameter of open should be "true" in order to make it async.

 xmlHttp.open('GET', theUrl, true);

That means that your request will be asynchronous and won't block the ui

Of course if you do this, you won't have the response right in the next line, so your function will be like this:

function httpGet(theUrl)
{
    var xmlHttp = new XMLHttpRequest();

    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            document.getElementById('result').innerHTML = xmlhttp.responseText;
        }
    }
    xmlHttp.open('GET', theUrl, false);
    xmlHttp.send(null);
}

Upvotes: 3

Related Questions