blazs
blazs

Reputation: 4845

jQuery: Retrieve data in a separate thread

I have a web application that has to perform the following task. For a chosen date range, it makes GET request to a web service for each date in the range; this can take a while, and because I want to visualize the data later, all the calls are synchronous (the result of each request gets stored into an array). This retrieval takes a while (several seconds) which means the main thread "freezes."

What would be a good way to avoid this? (E.g. doing the retrieval in a separate thread and getting notified once it's done.)

Upvotes: 1

Views: 267

Answers (3)

Lajos Arpad
Lajos Arpad

Reputation: 76434

In fact there is a simple solution. Let's implement a function which needs to be executed when all responses arrived:

function onFinished(responses) {
    //Do something
}

Now, let's suppose you have a function which returns the dates as array:

function getDates(range) {
    //Do something
}

Also, we need a getURL, like this:

function getURL(date) {
    //Do something
}

Finally, let's suppose you have a variable called dateRange which has the range you will use as input in getDates. So we can do this:

var requestDates = getDates(dateRange);
var requestsPending = requestDates.length;
var responses = [];
for (var requestIndex in requestDates) {
    $.ajax({
        url: getURL(requestDates[requestIndex]),
        method: "GET",
        //You might pass data as well here if needed in the form of
        //data: yourobject,
    }).done(function(data, textStatus, jqXHR) {
        //Handle response, parse it and store the result using responses.push()
    }).fail(function(jqXHR, textStatus, errorThrown) {
        //Handle failed requests
    }).always(function(param1, param2, param3) {
        if (--requestsPending === 0) {
            onFinished(responses);
        }
    });
}

This will send AJAX requests for each date you need and wait for their responses asynchronously, so, you effectively do not wait for the sum of the pending time, but for the longest pending time, which is a great optimization. It is impossible to solve this in a multithreaded fashion, as Javascript is single-threaded, so you need to wait asynchronously for the answers, as the requests won't wait for each-other on the server. If you own the server as well, then you do not need to send a request for each date, but to implement a server-side API function where you will handle date ranges, so client-side will send a single request and wait for the answer.

Upvotes: 1

knutesten
knutesten

Reputation: 594

You should make your GET-requests async and then visualize when all the requests have completed.

var get1 = $get(..
var get2 = $get(..
var get3 = $get(..

$.when(get1, get2, get3).done(function (...) {
  // do something with the response
  visualize();
});

Upvotes: 1

Jakub Jankowski
Jakub Jankowski

Reputation: 731

Consider using promises. They enable you to perform non-blocking calls to API. It's basically what you are asking for.

EDIT: You can use when() specifically to be notified, when all operations are done.

Upvotes: 2

Related Questions