spacemonkey
spacemonkey

Reputation: 19964

AJAX requests on Chrome using jQuery freezes page until they all complete

Code below works well on Firefox - displays progress bar which progresses on every file being uploaded, meanwhile in Chrome, it only displays progress bar at the end of transaction, also when I click "submit" button it freezes up until function completes.

var max = files.length + 1;
var progress_step = 0;
$.post(form.action, $(form).serialize(), function(response){
  var data = jQuery.parseJSON(response);
  if ("errors" in data){
    //...;
  }
  else if ("work_id" in data){
    var work_id = data.work_id;
    //initial increase of progress once Work was created
    progress_step = progress_step + 1;
    progress(progress_step, max);

    $.each(files, function(index, obj){
      uploadFile(work_id, obj);
      progress_step = progress_step + 1;
      progress(progress_step, max);
    });
  }
});

...

function uploadFile (w_id, obj) {    
  var base64_start = obj.src.indexOf(',') + 1;
  $.ajax({
    type: 'POST',
    url: '/works/upload_image',
    data: {work_id: w_id, pic: obj.src.substr(base64_start), pic_type: obj.file.type},
    processData: true,
    timeout: 60000,
    async: false,
    dataType: 'text'
  }); 
}

Upvotes: 7

Views: 16377

Answers (3)

CYoung
CYoung

Reputation: 357

Following SLaks remarks, I got the following to work with a recursive ajax call. The recursion is occurring on the ajax success callback.

var notesText = "";
        document.addEventListener('eInspListSynch', function (e) {

            notesText += "Number of records to save : " + inspRecordList.length.toString() + "\r\n";
            $("#SynchNotes").html(notesText);

            $("#synchProgressBar").progressbar({
                value: 0,
                max: inspRecordList.length
            }).show();

            // Recursive call.
            SendARecord(0);            

        });

        // Recursive call required here because Chrome will set browser updates off when asynch false is set for ajax calls.
        function SendARecord(currentRecord)
        {
            oneInspRecord.recordId = 99;
            oneInspRecord.weatherId = 5;
            var cntOfInspSaved = 0;
            oneInspRecord.contractorName = "CYoung";

            var pbVal = $("#synchProgressBar").progressbar("value");
            $("#synchProgressBar").progressbar("value", pbVal + 1);
            $("#synchProgressBar").show();

            $.ajax({
                type: "Post",
                url: '@Url.Content("~/SiteVisitInspection/SaveOneSiteVisitInspection/")',
                dataType: 'text',
                success: function (res) {
                    // If successful then delete the record from local cache.
                    notesText = inspRecordList[currentRecord].recordId.toString() + " written to server.\r\n" + notesText;                    
                    currentRecord = currentRecord + 1;
                    $("#SynchNotes").html(notesText);

                    if (currentRecord < inspRecordList.length) {
                        SendARecord(currentRecord);
                    }
                    else {
                        $("#synchProgressBar").hide();
                        notesText = "Completed synchronization.\r\n" + notesText;
                        $("#SynchNotes").html(notesText);
                        return;
                    }


                },
                error: function (error) {
                    console.log("Error in SaveOneSiteVisitInspection.");
                },
                data: oneInspRecord//,
                //async: false

            })


        }

Upvotes: 1

Peter Olson
Peter Olson

Reputation: 142921

If you don't want it to freeze, change async: false to async: true. Since this will make an asynchronous request, it might break the functionality of your progress bar, because it will move on to the next line of code before the request has completed. To fix this, use

success: function() { /*code in here*/ }

to put the code you want to activate when the request is finished.

Upvotes: 13

SLaks
SLaks

Reputation: 887453

Using async: false will freeze the page until the server replies.
Do not use it.

Get rid of that line and it will work fine.
However, it will be asynchronous, so you'll need to move your loop into the success callback.

Upvotes: 3

Related Questions