jQuery Deferred - Add callbacks to the Deferred contract at runtime

蓝咒 提交于 2019-12-08 06:49:26

问题


I need is to add an unknown number (known only at runtime) of .pipe() calls to the functions being monitored by jQuery's .when(). These calls will be based off of ajax calls made as a result of another asynchronous operation. Please see the code below for a more clear explanation:

$.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!'); });

Basically Level 1 and Level 3 need to execute in parallel. The Level 2s are all based off of the result of Level 1. And Level 1, all the Level 2s and Level 3 need to execute before All done.

Using the code above doesn't work, as the call to .pipe() does not affect what .when() is monitoring.

Is it possible to do what I want with jQuery's Deferred framework?

Thanks for any help.

Note: Earlier, I asked a very similar question, but I've realized the situation is significantly more complicated than what I illustrated there and I didn't want to cause confusion with the existing answers.

Original question


回答1:


It's not that much more complicated. If you want to execute all level 2 calls in parallel, just call $.when inside the .pipe callback and return that deferred object:

$.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!'); });

If you want to execute them sequentially, use .pipe again:

$.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!'); });

I have to say though that you should keep the number of Ajax calls to a minimum.



来源:https://stackoverflow.com/questions/12644372/jquery-deferred-add-callbacks-to-the-deferred-contract-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!