Ajax调用for循环,直到所有操作完成(错误或成功) [英] Ajax call in for loop wait until ALL done (error or success)

查看:111
本文介绍了Ajax调用for循环,直到所有操作完成(错误或成功)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在for循环中进行AJAX调用,我想等到所有这些操作完成后再进行操作.

I am making AJAX calls in a for loop and I would like to wait until all of them are done before doing something.

我正在尝试使用Promise,但是由于它不起作用,我缺少了一些东西.如果引发了错误,我的when调用会立即被引发,而我不想这样做.我想等到所有呼叫都完成,无论是成功还是错误.

I am trying to use promises but there is something that I'm missing because it won't work. If an error is fired, my when call is fired immediately and I don't want to. I want to wait until ALL calls are done, no matter if it's success or error.

完成所有调用后,我需要成功输入的条目数和错误数组.

When all calls are done, I want the number of entries that succeeded and an array of errors.

这是我的代码:

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,但是在我希望的时候都没有触发. 我在互联网上读了很多关于诺言的书,但是我肯定错过了一些东西,这使我发疯.

I tried with .done, .then, .always, but none of them fire when I wish to. I read a lot about promises on the internet but I'm definitely missing something and it's driving me crazy.

感谢您的帮助!

推荐答案

我发现最容易处理这些问题的方法是跟踪对象或数组中每个Async调用的状态.每次呼叫完成时,将其标记为已完成,然后检查是否还有其他运行.您甚至可以向对象中添加一个布尔值以检查asyncIsBusy还是ajaxStatus的属性.

The way I find easiest to handle these things is keeping track of the status of each of the Async calls in an object or array. Each time a call completes, flag it as done and check if there are any more running. You could even just add a boolean to your object to check if asyncIsBusy, or a property for ajaxStatus.

我在这里假设indexNametype来自resp.propertiesList(您似乎没有在任何地方使用您的i,所以我想您是偶然地将其遗漏了吗?).

I am assuming here that indexName and typeare coming from resp.propertiesList(you don't seem to use your ianywhere, so I guess you left that out by accident?).

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的原始对象为了.使用单独的功能可以避免此问题.

Note how I used a separate function to send the ajax, so a new closure is created for each object that you sent an ajax call for. You can't do all of this through anonymous functions because i would always be the maximum value in the callbacks (since the loop finishes before any ajax call is completed), leaving you no way to reference the original object you sent the Ajax for. Using a separate function circumvents this issue.

这篇关于Ajax调用for循环,直到所有操作完成(错误或成功)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆