无法等待多个AJAX调用完成

时间:2019-07-03 14:39:37

标签: jquery html

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

click事件中,我获取文件并遍历它们,然后将文件数据传递给First()函数调用,以获取唯一ID(VersionID)并传递那个{{1 }}在第二次调用VersionID函数时。

HTML

second()

JQuery

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

首次呼叫

$(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: false和在First()函数中使用async: true的另一件事,好像我在{{1 }}功能,我无法获得文件上传进度。

使用AJAX Second()时是否可以等待async: true函数完成然后继续循环?

1 个答案:

答案 0 :(得分:2)

您有两个问题。

首先,when需要传递一个或多个 thenable对象,但是您要传递undefinedsecond没有返回声明。但是,使用when是没有意义的,因为您不是并行运行多个函数。

第二个问题是,尽管when不会调用done回调,直到您传递给它的所有内容都完成了……for循环不会等待以完成when


有两种方法可以解决此问题:

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

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