Ajax调用for循环等待,直到完成所有操作(错误或成功)

时间:2015-09-25 08:24:57

标签: javascript jquery ajax promise

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

我正在尝试使用承诺,但有些东西我不在,因为它不会起作用。如果错误被触发,我的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,但是当我希望时,它们都没有发射。 我在互联网上看了很多关于承诺的内容,但我肯定错过了一些东西而且它让我发疯了。

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

import datetime text_date = [item.strip() for item in input_text.split('\n') if "Delivered On:" in item][0][41:-5] datetime.datetime.strptime(text_date.replace(".",""), "%m/%d/%Y %I:%M %p") 可以为您提供帮助,您可以在此处找到npm包 - https://www.npmjs.com/package/q

答案 1 :(得分:1)

我最容易处理这些事情的方法是跟踪对象或数组中每个Async调用的状态。每次呼叫完成时,将其标记为已完成并检查是否还有呼叫。您甚至可以在对象中添加一个布尔值,以检查asyncIsBusyajaxStatus的属性。

我假设indexNametype来自resp.propertiesList(您似乎无法在任何地方使用i,所以我想你离开了那是偶然的吗?)。

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。使用单独的功能可以避免这个问题。

答案 2 :(得分:0)

尝试在ajax调用中设置async:false

var promise = _TOOLS.Ajax({
                    type: 'POST',
                    url: urlTest,
                    data: documentToSend,
                    async: false,
                    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.");
                    }
                });

答案 3 :(得分:0)

寻求递归方法:

ajaxLoopArray(myArray, function(){ /* do something when finish */ });

function ajaxLoopArray(someArray, callbackFunction){
    if(someArray.length>0){ //condition to break the loop
        data = someArrapy.pop(); // pop removes the last element from an array and returns that element.
        $.ajax({
            data
        }).done(function(x){
            //success
        })
        .fail(function(){
            //catch the error here
        })
        .always(function(){
            ajaxLoopArray(someArray, callbackFunction); //recursive call: keep on looping independently of success or error
        });
    }else{
        callbackFunction(); //when everything was done
    }
}