jQuery.when()没有按预期工作

时间:2016-05-18 09:14:00

标签: javascript jquery

我有一系列异步操作,其响应必须同步才能运行最终操作。我使用延迟对象和 when() done()方法来实现此目的,但出于某种原因,当调用响应的第一个 resolve()时,始终执行done()中的最终操作。

这是我的代码,缩短了一点以使其更清晰:

       // Central function that creates a Deferred object and returns a
       // Promise from it. when the passed request is done, 
       // the Deferred is resolved
       var getData = function(url, successFunction) {
            var deferred = $.Deferred();
            $.ajax({
                url: url,
                method: 'get',
                dataType: 'json'
            }).done(function(p) {
                successFunction(p);
                deferred.resolve(p);
            }).fail(function(p){
                deferred.reject(p);
            });
            return deferred.promise();
        };

        // Success actions to be called for each asynchronous request

        var populateDestinations = function(data) {
            // synchronous actions on DOM
        };

        var populateTaxes = function(data) {
            // synchronous actions on DOM
        };

        var populatePayment = function(data) {
            // synchronous actions on DOM
        };


        // Actions that return a Promise to control the resolution of 
        // all the deferred objects

        var getCustomerDestinations = function(customerId) {
            var url = $modal.data('url_destinations') + customerId;
            return getData(url, populateDestinations);
        };

        var getCustomerTaxes = function(customerId) {
            var url = $modal.data('url_taxes') + customerId;
            return getData(url, populateTaxes);
        };

        var getCustomerPayment = function(customerId) {
            var url = $modal.data('url_payment') + customerId;
            return getData(url, populatePayment);
        };

        var populateFields = function() {
            // final actions
        };


        $.when(getCustomerDestinations(customer_id),
                getCustomerTaxes(customer_id),
                getCustomerPayment(customer_id))
        .done(function(){

             populateFields();

        });

正在调用populateFields(),其中一个"承诺"功能已解决,而不是在解析所有时。

知道我做错了什么吗?也许我还没有掌握Deferred对象的概念。

1 个答案:

答案 0 :(得分:2)

你真的不需要使用任何延迟对象来跟踪ajax调用,而只需使用$.ajax$.when()返回的promise对象。

JQUERY CODE:

var getData = function(url, successFunction) {
        return $.ajax({
            url: url,
            method: 'get',
            dataType: 'json'
        }).then(function(p) {
            successFunction(p);
        },function(p){
            //process error using error callback, 
            //just like success callbacks
        });
    };

我要处理单独的ajax调用,您可以使用.then()代替.done()& .fail(),因为这些不会返回任何承诺对象,而不是.then()来追踪.when()中的承诺对象。

其余代码将按原样运行。

jQuery论坛说:

  

jQuery 1.8 开始,deferred.then()方法返回一个新的承诺,可以通过函数过滤延迟的状态和值,替换现在已弃用的deferred.pipe()方法。 doneFilterfailFilter函数会过滤原始延期的已解决/已拒绝状态和值。 progressFilter函数过滤对原始延迟的notify或notifyWith方法的任何调用。这些过滤函数可以返回一个新值,传递给promise .done().fail()回调,或者它们可以返回另一个可以通过它的可观察对象(Deferred,Promise等)解决/拒绝状态和承诺回调的价值。

反驳链接: