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 - Three.js 将对象附加到骨骼

javascript - 文本框中的占位符和光标对齐方式

javascript - 让 JQuery 识别新添加的元素

jquery - 无法将图片上传到我的域

jquery - Firefox:模糊事件仅在所选元素外部第二次单击时触发 有什么方法可以修复它吗?

java - GWT 刷新编译周期

javascript - jQuery、CSS : auto-color HTML lists?

javascript - 单击复选框时会触发两次 jQuery 单击事件

jquery - 如何获取 Select2 下拉列表中的所有值?

javascript - ajax加载后显示内容