当所有的ajax请求完成后,那么

时间:2014-12-12 13:07:19

标签: jquery ajax jquery-deferred

我需要做一堆ajax请求(我需要这样做以填充一些选择框),并且在加载所有内容后,隐藏加载面板。

如果我这样做,这非常有效:

$.when(
    $.getJSON(applicationUrl + "data/codiciPaese.json", function (json) {
        data.codiciPaese = json;
        $.each(data.codiciPaese, function (index, item) {
            $(".codiciPaese").append($('<option>', {
                value: item.code,
                text: item.code + " - " + item.name
            }));
        });
    }),
    $.getJSON(applicationUrl + "data/regimiFiscali.json", function (json) {
        data.regimiFiscali = json;
        $.each(data.regimiFiscali, function (index, item) {
            $(".regimiFiscali").append($('<option>', {
                value: item.code,
                text: item.code + " - " + item.name
            }));
        });
    }),
    $.Deferred(function (deferred) {
        $(deferred.resolve);
    })
).done(function () {
    $('#loading').fadeOut(800, function () {
        // something else
    });
});

但是,因为我想采用DRY原则:)并且因为会有两个以上的请求,所以我试图将getJSON请求包装到每个周期中:

var elementsToGet = { // I'll reuse this to get the values elsewhere
    codiciPaese: "HY",
    regimiFiscali: "RF01",
};

$.when(
    $.each(elementsToGet, function (element, defaultValue) {
        $.getJSON(applicationUrl + "data/"+element+".json", function (json) {
            data.element = json;
            $.each(data.element, function (thisIndex, thisElement) {
                $(parent + " ."+element).append($('<option>', {
                    value: thisElement.code,
                    text: thisElement.code + " - " + thisElement.name
                }));
            });
        });
    }),
    $.Deferred(function (deferred) {
        $(deferred.resolve);
    })
).done(function () {
    $('#loading').fadeOut(800, function () {
        // something else
    });
});

问题是这种方式“延迟”不再使用,因此加载面板在加载所有数据之前消失。我做错了什么?

3 个答案:

答案 0 :(得分:3)

我认为您可以向$.when提供多项承诺:

var promises = $.map(elementsToGet, function(element, defaultValue) {
        return $.getJSON(applicationUrl + "data/" + element + ".json", function(json) {
            $.each(data.element, function(thisIndex, thisElement) {
                $(parent + " ." + element).append($('<option>', {
                    value: thisElement.code,
                    text: thisElement.code + " - " + thisElement.name
                }));
            });
        });
    });

$.when.apply(null, promises).done(function() {
    $('#loading').fadeOut(800, function() {
        // something else
    });
});

注意,.apply(null, promises)在这里是因为$.when期望延迟对象作为$.when( d1, d2, d3 )而不是数组传递。

答案 1 :(得分:0)

这个怎么样?

var functionToCall = 2;
var functionCalled = 0;

$.getJSON(applicationUrl + "data/codiciPaese.json", function (json) {
    data.codiciPaese = json;
    $.each(data.codiciPaese, function (index, item) {
        $(".codiciPaese").append($('<option>', {
            value: item.code,
            text: item.code + " - " + item.name
        }));
    });
    AmIDone();
});

$.getJSON(applicationUrl + "data/regimiFiscali.json", function (json) {
    data.regimiFiscali = json;
    $.each(data.regimiFiscali, function (index, item) {
        $(".regimiFiscali").append($('<option>', {
            value: item.code,
            text: item.code + " - " + item.name
        }));
    });
    AmIDone();
});

function AmIDone() {
    functionCalled++;
    if (functionCalled == functionToCall) {
        $('#loading').fadeOut(800, function () {
            // something else
        });
    }
}

答案 2 :(得分:0)

如果我收到您的问题,您需要在ajax请求后调用ajax请求并执行某些操作。 在这里你将有一个gerenal的想法。您可以根据自己的需要进行更改。

//The data you want to send to server side
var dt1={ 
        dt1:val1,
        dt2:$("#txt_EmailLogin").val()
    };

//Your ajax-1 request.
var request =$.ajax({//http://api.jquery.com/jQuery.ajax/
     url: "yourServer.php",
     type: "POST",
     data: dt1,
     dataType: "json"
});//End of request-1

//Ajax-1 Done catch JSON from PHP 
request.done(function(dataset){
    for (var index in dataset){ 
         dataPHPtoJsJS=dataset[index].dataPHPtoJs;
         asManyasYouWantJS=dataset[index].asYouWant;
     }

     //JavaScript conditions. Here you can control the behaivior of your html object, based  on your PHP response. HERE YOU CAN HIDE YOUR LOAD PANNEL - IF IS THE CASE.
     if(dataPHPtoJsJS){
        $( "#idYourHtmlElement" ).removeClass( "class1" )
        $( "#idYourHtmlElement" ).addClass( "class2" )
     }

    /////////////////////////////////////////////////////////////
    //Here will be your second Ajax that will be trigged after the Ajax-1 will done. Only repeat everything
    var dt2={ 
        dt3:val1,
        dt4:$("#txt_EmailLogin").val()
    };

    //Your ajax-2 request.
    var request =$.ajax({//http://api.jquery.com/jQuery.ajax/
         url: "yourServer2.php",
         type: "POST",
         data: dt2,
         dataType: "json"
        });

        request.done(function(dataset){
            for (var index in dataset){ 
                dataPHPtoJsJS=dataset[index].dataPHPtoJs;
                asManyasYouWantJS=dataset[index].asYouWant;
            }//End of for

            //Here you can call another Ajax AJAX-3, you can controll your HTML elements - HERE YOU CAN HIDE YOUR LOAD PANNEL - after the second AJAX is done
        });//End of DONE-2

    //Ajax-2 Fail 
    request.fail(function(jqXHR, textStatus) {
        alert("Request -1 failed: " + textStatus);
    });

    /////////////////////////////////////////////////////////////
});//End of AJAX-1

//Ajax-1 Fail 
request.fail(function(jqXHR, textStatus) {
            alert("Request -1 failed: " + textStatus);
});