使用jQuery的Chrome上的AJAX请求冻结页面,直到它们全部完成

时间:2021-09-26 19:45:55

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.

下面的代码在Firefox上运行良好 - 显示每个上传文件的进度条,同时在Chrome中,它只显示交易结束时的进度条,当我点击“提交”按钮时它冻结直到功能完成。

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'
  }); 
}

3 个解决方案

#1


12  

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

如果您不希望它冻结,请将async:false更改为async:true。由于这将产生异步请求,因此它可能会破坏进度条的功能,因为它将在请求完成之前转到下一行代码。要解决此问题,请使用

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

成功:function(){/ *代码在这里* /}

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

在请求完成时放置要激活的代码。

#2


3  

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

使用async:false将冻结页面,直到服务器回复。不要使用它。

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.

摆脱那条线,它会工作正常。但是,它将是异步的,因此您需要将循环移动到成功回调中。

#3


1  

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

在SLaks评论之后,我得到以下内容来处理递归的ajax调用。递归发生在ajax成功回调上。

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

            })


        }

#1


12  

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

如果您不希望它冻结,请将async:false更改为async:true。由于这将产生异步请求,因此它可能会破坏进度条的功能,因为它将在请求完成之前转到下一行代码。要解决此问题,请使用

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

成功:function(){/ *代码在这里* /}

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

在请求完成时放置要激活的代码。

#2


3  

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

使用async:false将冻结页面,直到服务器回复。不要使用它。

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.

摆脱那条线,它会工作正常。但是,它将是异步的,因此您需要将循环移动到成功回调中。

#3


1  

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

在SLaks评论之后,我得到以下内容来处理递归的ajax调用。递归发生在ajax成功回调上。

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

            })


        }