javascript - 循环中的 Ajax 调用等到全部完成(错误或成功)

标签 javascript jquery ajax promise

我在 for 循环中进行 AJAX 调用,我想等到所有调用都完成后再做某事。

我正在尝试使用 promises,但我缺少一些东西,因为它不起作用。如果触发错误,我的 when 调用会立即触发,而我不想这样做。我想等到所有调用都完成,无论是成功还是错误。

当所有调用完成后,我想要成功的条目数和错误数组。

这是我的代码:

for (var i = 0; i < resp.propertiesList.length; i++) {
    var documentToSend = { 
        indexName: indexName, 
        type: type, 
        jsonContent: blabla 
    };

    var promise = _TOOLS.Ajax({
        type: 'POST',
        url: urlTest,
        data: documentToSend,
        contentType: 'application/x-www-form-urlencoded',
        dataType: 'json',
        success: function (dataResponse) {
            numberOfEntriesSuccess++;
        },
        error: function (xhr, ajaxOptions, errorThrown) {
            var errorResponse = JSON.parse(xhr.responseText);
            errorsList.push(errorResponse.ExceptionMessage + ". Skipping line.");
        }
    });

    promises.push(promise);
}

//When all ajax calls are finished, load report page and display informations
$.when.apply($, promises).done(function() { 
    console.log("DONE " + promises.length); 
    console.log(errorsList); 
})

我尝试了 .done.then.always,但它们都没有在我希望时触发。 我在 Internet 上阅读了很多关于 promises 的内容,但我确实遗漏了一些东西,这让我发疯。

感谢您的帮助!

最佳答案

我发现处理这些事情最简单的方法是跟踪对象或数组中每个异步调用的状态。每次调用完成时,将其标记为已完成并检查是否还有运行。您甚至可以只向您的对象添加一个 bool 值以检查 asyncIsBusyajaxStatus 的属性。

我在这里假设 indexNametype 来自 resp.propertiesList(你似乎没有使用你的 任何地方,所以我猜你不小心把它漏掉了?)。

for (var i = 0; i < resp.propertiesList.length; i++) {
    var documentToSend = { 
        indexName: indexName, 
        type: type, 
        jsonContent: blabla 
    };

    sendDocumentAjax(resp.propertiesList[i], documentToSend)
}

function sendDocumentAjax(listObj, documentData){
    listObj.ajaxStatus = 'pending';
    _TOOLS.Ajax({
        type: 'POST',
        url: urlTest,
        data: documentData,
        contentType: 'application/x-www-form-urlencoded',
        dataType: 'json',
        success: function (dataResponse) {
            listObj.ajaxStatus = 'success';
        },
        error: function (xhr, ajaxOptions, errorThrown) {
            var errorResponse = JSON.parse(xhr.responseText);
            listObj.ajaxStatus = 'error: '+ errorResponse;
        }
        always: checkAjaxStatuses;
    });
}

function checkAjaxStatuses(){
    var pending = [];
    var successes = [];
    var errors = [];
    for (var i = 0; i < resp.propertiesList.length; i++) {
        if(resp.propertiesList[i].ajaxStatus === 'pending'){
            pending.push(resp.propertiesList[i]);
        }
        if(resp.propertiesList[i].ajaxStatus === 'success'){
            successes.push(resp.propertiesList[i]);
        }
        if(resp.propertiesList[i].ajaxStatus.indexOf('error') !== -1){
            errors.push(resp.propertiesList[i]);
        }
    }

    console.log('ajax completed.');
    console.log(pending.length + ' pending.');
    console.log(successes.length + ' succeeded.');
    console.log(errors.length + ' failed.');
}

请注意我是如何使用单独的函数来发送 ajax 的,因此会为您发送 ajax 调用的每个对象创建一个新的闭包。您不能通过匿名函数完成所有这些操作,因为 i 始终是回调中的最大值(因为循环在任何 ajax 调用完成之前完成),使您无法引用原始函数您发送 Ajax 的对象。使用单独的函数可以避免这个问题。

关于javascript - 循环中的 Ajax 调用等到全部完成(错误或成功),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32777895/

相关文章:

javascript - 解构多级并将默认值分配给第一级对象

javascript - 如何在 JavaScript 中设置 div 的百分比宽度?

javascript - 如何在 IE 中使用 javascript 从客户端获取文件大小?

javascript - 无法将 Dropzone 附加到 AJAX 加载的 DIV

java - 如果响应中有多个值,如何从不同文本字段中的ajax响应中获取值?

javascript - 来自外部文件中服务的 ag-grid 绑定(bind)

javascript - bootstrap 下拉菜单不下拉

javascript - 跨域 jquery ajax 未获取 json

javascript - 跨域子窗口 DOM 引用

javascript - JQuery如何捕获回车键或双击选择->选项标签