Wait until all jquery ajax request are done? (part

2019-09-17 19:46发布

I checked this post and the answer is really good: Wait until all jQuery Ajax requests are done?

But I just want to be more generic: I wonder how we can use this logic for a List of services (ajaxservices) and list of callbacks e.g.

ajaxservices = ["url-getdata1", "url-getdata2"];
callbacks = [callbackdata1, callbackdata2];
callbackdata1 = function (data){...}

$.when(/*somehow call all ajaxservices[]*/).done(function (dataList) {
            for (var i = 0; i < callbacks.length; i++) {
                callbacks[i](dataList???[i][0]);/* somehow pass the data as parameter*/
            }

        });

Thanks!

More Info: http://api.jquery.com/jQuery.when/

2条回答
对你真心纯属浪费
2楼-- · 2019-09-17 20:06

Do not use eval, but the apply method of functions which takes an array of arguments to call the function with:

var ajaxservices = ["url-getdata1", "url-getdata2"],
    callbacks = [callbackdata1, callbackdata2];
// assuming a function "callAjax()" that takes an url and returns a promise

var promises = $.map(ajaxservices, callAjax); // loop and generate array

$.when.apply($, promises).done(function () {
    for (var i = 0; i < callbacks.length; i++) {
        callbacks[i].apply(null, arguments[i]);
    }
});
查看更多
叛逆
3楼-- · 2019-09-17 20:20

*Updated - DIDN'T WORK AS I EXPECTED (see real solution below)

Failed Approach

I found a way out using eval... it is not fully tested but seems ok. Please feels free to post your comments/trade-off.

callAjax is a method that receive an url and return a promise such as return $.ajax(...), but since I should executed it using .when statement I put all the calls in a string to later eval them inside the .when statement.

convertAjaxCallsToString = function () {
    var result = '';
    for (var i = 0; i < ajaxservices.length; i++) {
        result += "callAjax(ajaxservices[" + i + "])";
        if (i + 1 < ajaxservices.length) {
            result += ",";
        }
    }

    return result;
}

Since I don't expect more than 10 ajax calls, I hardcoded these 10 responses (arg 0 - 9) as you see below... If I only use 3 ajax services, then only 3 arg should have value and the others will be undefined and never will be eval because callbacks.length should be 3 as well.

var ajaxcalls = _self.convertAjaxCallsToString();

$.when(eval(ajaxcalls)).done(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
    for (var i = 0; i < callbacks.length; i++) {
        //If you expect a page response, Each argument is an array with the following structure: [ data, statusText, jqXHR ]
        var data = eval('arg' + i)[0];
        callbacks[i](data);
    }

});

Posible Solution

the call ajax didn't work as I expected so I decided to use another approach. Tested and works fine!

$.when(ajax(0), ajax(1), ajax(2), ajax(3), ajax(4), ajax(5), ajax(6), ajax(7), ajax(8), ajax(9))
.done(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
        for (var i = 0; i < callbacks.length; i++) {
            //If you expect a page response, Each argument is an array with the following structure: [ data, statusText, jqXHR ]
            var data = eval('arg' + i)[0];
            callbacks[i](data);
        }

    });

Where ajax is will return 0 if there is not ajax service to call.

var ajax = function (index) {
            if (index < ajaxservices.length) {
                return callAjax(ajaxservices[index]);
            }

            return 0;
        }
查看更多
登录 后发表回答