jQuery Deferred - 在运行时向延迟契约添加回调

时间:2012-09-28 17:04:30

标签: javascript jquery jquery-deferred

我需要的是添加一个未知的数字(仅在运行时知道).pipe()调用jQuery的.when()监视的函数。这些调用将基于由于另一个异步操作而产生的ajax调用。请参阅下面的代码以获得更清晰的解释:

$.when(
    $.ajax({ 
        async: true,        
        success: function (data, textStatus, jqXhr) {
            console.log('Level 1')

            for(var i = 0; i < data.length; i++)
                jqXhr.pipe(
                    $.ajax({  
                        data: data[i],                                                              
                        async: true,        
                        success: function (data, textStatus, jqXhr) {
                            console.log('Level 2');
                        },       
                    })
                );
        },       
    }),
    $.ajax({
        async: true,        
        success: function (data, textStatus, jqXhr) {
            console.log('Level 3');
        },       
    })
).done(function(){ console.log('All done!'); });

基本上,1级和3级需要并行执行。级别2都基于级别1的结果。级别1,所有级别2和级别3都需要在完成所有之前执行。

使用上面的代码不起作用,因为对.pipe()的调用不会影响.when()监视的内容。

是否可以使用jQuery的Deferred框架做我想要的事情?

感谢您的帮助。

注意:早些时候,我问了一个非常相似的问题,但我意识到情况要比我在那里说明的要复杂得多,而且我不想让现有答案混淆。

Original question

1 个答案:

答案 0 :(得分:1)

它并没有那么复杂。如果要并行执行所有2级调用,只需在$.when回调中调用.pipe并返回该延迟对象:

$.when(
    $.ajax({        
        // ...      
    }).pipe(function(data) {
        // concise way to make the Ajax calls for each value
        var deferreds = $.map(data, function(value) {
            return $.ajax({data: value, /*...*/});
        });
        return $.when.apply($, deferreds);
    }),
    $.ajax({        
        // ...       
    })
).done(function(){ console.log('All done!'); });

如果您想按顺序执行它们,请再次使用.pipe

$.when(
    $.ajax({        
        // ...      
    }).pipe(function(data) {
        // A "dummy" resolved deferred object 
        var deferred = (new $.Deferred()).resolve();
        $.each(data, function(value) {
            deferred = deferred.pipe(function() {
                return $.ajax({data: value, /*...*/});
            });
        });
        return deferred;
    }),
    $.ajax({        
        // ...       
    })
).done(function(){ console.log('All done!'); });

我必须说,你应该将Ajax调用的数量保持在最低限度。