1

我需要向 jQuery 的 .when() 监控的函数添加未知数量的 .pipe() 调用(仅在运行时知道)。这些调用将基于另一个异步操作导致的 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!'); });

基本上 Level 1 和 Level 3 需要并行执行。Level 2s都是基于Level 1的结果。而Level 1,所有的Level 2s和Level 3都需要在All done之前执行。

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

可以用 jQuery 的 Deferred 框架做我想做的事吗?

谢谢你的帮助。

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

原始问题

4

1 回答 1

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 调用的数量保持在最低限度。

于 2012-09-28T18:03:27.830 回答