user516883
user516883

Reputation: 9378

javascript Race condition issue

I have two function, one function is a reload function that does a ajax web call to get data. the other is the item loader that loads the data. The problem is that the function that loads the data item has not value yet because of the ajax call made. Anyway of fixing this besides calling setTimeout? Thanks in advance for any help.

function reload(index) {
    _ListData[index] = null;
    DisplayInformation.GetTemplateTableInformation(
        ListManager.listReportId(),
        ListManager.listParameters(),
        ListManager.listSortParams(),
        TableReportHelper_TemplateRelatedAction,
        reloadRange.min, 
        reloadRange.num,
        function(templateItemIfo) {//success callback causes issues with race conditon in the function itemLookaheadCallback because _ListData[index] = null;
            itemLookaheadCallback(templateItemIfo, index);
        });
}

Here is the function that tries to load the item that was called in the reload callback

 function loadDataCallback(lookAheadData, index, loadNeighbors) {
    //Store the received value
    var item = _ListData[index];//this will be null because of _ListData[index] = null;
    item.data = lookAheadData.TemplateInformation;

};

Upvotes: 1

Views: 705

Answers (3)

Garrett Bluma
Garrett Bluma

Reputation: 1312

I know this looks like a race condition, but I'm going to go out on a limb and suggest that it's actually a scope issue.

_ListData exists inside of the reload() function, and if I recall correctly a callback might inherit that scope and still make it accessible one level deep.

function reload(index) {
    _ListData[index] = null;
    ...
}

But the callback of a callback (which it looks like you might be doing) will probably loose that scope and exist in a completely anonymous scope.

reload -> itemLookaheadCallback -> loadDataCallback

The solution? Consider using window to define a globally accessible location for that variable. (window is always global).

Here's the changes that would make that happen:

function reload(index) {
    window._ListData[index] = null;
    ...
}

function loadDataCallback(lookAheadData, index, loadNeighbors) {
    var item = window._ListData[index];
    ...
};

Anyway, that's just a guess. Probably wrong, but relatively easy to verify.

Upvotes: 0

Sid
Sid

Reputation: 7631

You can make a synchronous call by using async=False in your ajax call. for example:

$.ajax({
            type: 'GET',
            url: '/yourUrl/',
             dataType: 'json',
            success: function(data) {

            },
            data: {},
            async: false
        });

p.s.: Using jQuery to make Ajax call here.

Upvotes: -1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324640

Put the code to load the items inside the "success callback".

Alternatively, make the AJAX call synchronous, although this should be avoided because on slow connections or for large amounts of data it may appear like your page has frozen.

Upvotes: 2

Related Questions