温馨提示:本文翻译自stackoverflow.com,查看原文请点击:jquery - Unable to wait for multiple AJAX calls to finish
html jquery

jquery - 无法等待多个AJAX调用完成

发布于 2020-03-27 11:21:47

我正在尝试将文件发送到我的API,并希望在选择多个文件并使用两个不同的Post调用时一个接一个地执行

click事件中,我通过他们获得的文件和循环然后将文件数据传递给First()函数调用来找回的唯一ID( VersionID),并通过该VersionID做第二个呼叫时second()功能。

的HTML

 <div class="progress">
        <div class="progress-bar">0%</div>
    </div>    
    <div id="status"></div>

jQuery查询

$(function () {
            var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;               
            var status = $('#status');
            $('#btnUploadFile').on('click', function () {
                $("#btnUploadFile").attr("disabled", true);
                var files = $("#fileUpload").get(0).files;
                var input = document.getElementById('fileUpload');
                for (var i = 0; i < input.files.length; ++i) {
                    var file = input.files[i];
                    first(9, file.name, (file.size / 1000), file.name.split('.')[1], function (versionID) {
                        $.when(second(versionID, files[i])).done(function(){
                            status.html('Uploading ' + i + ' of ' + input.files.length)});                        
                    });
                };
            });
        });

首次通话

function first(libid, filename, filesize, fileextension, callback) {
            var form = new FormData();
            form.append("LibId", libid);
            form.append("FileName", filename);
            form.append("FileSize", filesize);
            form.append("FileExtension", fileextension);
            var settings = {
                "async": false,
                "crossDomain": true,
                "url": "URL",
                "method": "POST",                  
                "processData": false,
                "contentType": false,
                "mimeType": "multipart/form-data",
                "data": form
            }
            $.ajax(settings).done(function (response) {
                callback(response);
            });
        };

第二次通话

function second(versionId, fileData) {
            var data = new FormData();
            data.append('UploadedFiles', fileData);
            var bar = $('.progress-bar');
            var percent = $('.progress-bar');            
            $.ajax({
                async: true,
                crossDomain: true,
                url: "URL" + Math.floor(versionId).toString(),
                method: "POST",
                processData: false,
                contentType: false,
                mimeType: "multipart/form-data",
                data: data,                    
                xhr: function () {
                    var xhr = $.ajaxSettings.xhr();
                    xhr.onprogress = function e() {
                        // For downloads
                        if (e.lengthComputable) {
                            console.log(e.loaded / e.total);
                        }
                    };
                    xhr.upload.onprogress = function (e) {
                        // For uploads
                        if (e.lengthComputable) {                            
                            var percentVal = parseInt((e.loaded / e.total * 100), 10);
                            console.log("Loaded " + parseInt((e.loaded / e.total * 100), 10) + "%");
                            var percentValue = percentVal + '%';
                            bar.width(percentValue);
                            percent.html(percentValue);                            
                        }
                    };
                    return xhr;
                }
            }).done(function (response) {                
                percent.html("Completed");                 
            }).fail(function (e) {
                console.log("failed");
            });
        };

问题是$.when(second(versionID, files[i])).done....似乎没有等待继续循环。

当前行为:

它等待First()功能完成,然后触发 Sencond()功能,但是Second()在启动新First()功能之前不等待功能。

预期行为

等待First()功能完全完成,然后再等待功能完全完成,然后 Second()循环回到下一个文件并First()再次调用功能。

我使用其他的事情async: falseFirst()功能和async: trueSecond()功能,如果我不使用async: trueSecond()功能,我不能得到文件上传进度。

second()使用AJAX时是否可以等待函数完成再继续循环async: true

查看更多

查看更多

提问者
Ali
被浏览
151
Quentin 2019-07-03 22:47

你有两个问题。

首先,when需要传递一个或多个可转换的对象,但是您正在传递undefinedsecond没有返回声明。when但是没有必要使用,因为您不是并行运行多个功能。

第二个问题是,虽然when不会调用done回调,直到一切,你传递给它做......的for循环不会等待when完成。


您可以采用两种方法来解决此问题:

  1. 删除for循环
    • 保持 var i
    • first增量i
    • 调用first递归式second(直到iinput.files.length
  2. 使用async/ await管理从中返回的承诺$.ajax(这将使您保持循环)。

如果要支持较旧的浏览器,则后一种方法将需要使用Babel这样的编译器。