Question

Today one of the weirdest things i have ever seens just happened. I have a loop in a page that does a synchronous ajax request for each element of the loop. Since it was taking too long i decided to stop the loop by refreshing the page.

When the page loaded i couldn't click on any element of the page so i checked Firebug console and i saw that the ajax calls of the previous loop were still being done (the loop is set to start after i click on a link, so it can't start as soon as page loads). To stop the loop i had to close the current tab and open my page in a new one.

It's worth mentioning that i have a datatables table on that page and i have enabled the option to save the table state, maybe this is interfering with my code (the loop itself is not part of the datatables initialization, though it uses data from the table).

I have also noticed that some things of the loop aren't being done. It should've changed the page of the datatable by time to time, and it should've written in the javascript console, both things don't happen after i refresh the page, the ajax calls are still going though.

Here's the code where the loop is contained:

//This variable will contain a reference to the datatable
var oTable;
var isWorking=false;
//Change the datatables page
function changeTablePage(oTable, page, clear){
    if(clear){
        oTable.fnClearTable();
        oTable.fnDraw();
    }
    oTable.fnPageChange(page);
}

//This part is inside a document.ready block
    $(document).on("click", ".validation-all-click", function(event){
        if(!isWorking){
            isWorking=true;
            //saves the current page, will be needed for later
            var page=oTable.fnPagingInfo().iPage;
            var numberPage=0;
            var done=false;
            while(!done){
                console.log("page: "+numberPage);
                changeTablePage(oTable, numberPage, false);
                var nNodes = oTable.fnGetNodes();
                var len=nNodes.length;
                $('.validation-click', nNodes).each(function( index, value ){
                    //id of the element to be validated
                    var id=$(value).data("rowid");
                    //Calls the validation url
                    $.ajax({
                        url: "/validate?id="+id,
                        async: false
                    });
                });
                //if the datatables page has 0 items, then it's done
                if(len==0){
                    done=true;
                }
                numberPage++;
            }
            //goes back to the original page
            changeTablePage(oTable, page, true);
            isWorking=false;
        }

});

I don't want this behavior to happen, but i have no idea on why it's happening and how to prevent it

Était-ce utile?

La solution 2

I have solved by adding a variable that will stop the loop when i exit the page:

var stopLoop=false
$( window ).unload(function() {
    stopLoop=true;
});

both loops will now check if this variable is false before executing the code inside the loop. This works on Firefox but not on Chrome though.

-- EDIT --

In the end i have solved by editing the code in order to make the ajax calls asynchronous and using the callback functions to continue the cycle, though it was no simple task (some days later i found a new solution that allowed me to do all that i needed in a single call when i found out how to recover the parameters used by datatables to retrieve data, but this has nothing to do with the original question). So, for future references: expect this "weird" behaviour when making a loop with ajax synchronous calls

Autres conseils

Thanks for sharing your story. I don't see any specific question in the post, so I'll just comment on whatever I feel like.

As I understand it, browsers aren't required to redraw the UI while JavaScript is running. Since there's a script blocking on a synchronous ajax request, maybe it's to be expected that you don't see the changes to the table until the loop finishes.

Furthermore, it may also be that the browser isn't required to destroy a page while its scripts are running. That would explain why you saw requests in Firebug after refreshing the page--perhaps the previous copy of the page was still running in a hidden state.

edit: valepu reports in a comment, below, that the table does change while the script is running. That's fine. The browser can probably determine that it can redraw the UI during the ajax call (which doesn't affect the JavaScript environment). valepu also clarifies that the visual updates stop after refreshing the page, though the requests continue to go out. This is also consistent with the idea that the browser has just hidden the previous page (until it finishes) and loaded up a new copy of the page when refreshing.

As for how to prevent it: the most reliable way would be to use asynchronous requests, or otherwise yield between requests. Sorry, folks.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top