What is cleanest way to turn Array of JQuery Promises into a JQuery Promise of an Array?

前端 未结 2 1079
失恋的感觉
失恋的感觉 2020-12-05 15:38

I run into the situation where I have multiple JQuery Promises in an Array

var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]
<         


        
相关标签:
2条回答
  • 2020-12-05 15:45

    You can just apply the array as the arguments to $.when.

    var promiseOfArray = $.when.apply($, arrayOfPromises);
    

    To make the usage of this clearer, I like adding a method to $:

    $.whenall = function(arr) { return $.when.apply($, arr); };
    

    Now you can do:

    $.whenall([deferred1, deferred2, ...]).done(...);
    

    Update: By default, the done handler gets each result passed as a separate argument; you don't get an array of results.

    Since you need to handle an arbitrary number of Deferreds, you can use the special implicit arguments object to loop over the results.

    $.whenall([d1, d2, ...]).done(function() {
        for (var i = 0; i < arguments.length; i++) {
            // do something with arguments[i]
        }
    });
    

    If you really just want to join the string result of all your Deferreds, we can employ a little array hackery. arguments is array-like, but is not an Array:

    $.whenall([d1, d2, ...]).done(function() {
        alert(Array.prototype.join.call(arguments, ','));
    });
    

    If you want to return an array of results to your done callback, we can tweak whenall to do it:

    $.whenall = function(arr) {
        return $.when.apply($, arr).pipe(function() {
            return Array.prototype.slice.call(arguments);
        });
    };
    
    0 讨论(0)
  • 2020-12-05 16:03

    It also bothered me alot to always type the "ugly" line $.when.apply when we need to invoke it on multiple promises. But Function.prototype.bind for the rescue!

    var when = Function.prototype.apply.bind( jQuery.when, null );
    

    Now, we can just call

    when( someArrayWithPromises ).done(function() {
    });
    

    Function.prototype.bind is part of ES5 and is very widely available across browsers. There are a ton of easy shims available if you need to support very old'ish browsers aswell

    0 讨论(0)
提交回复
热议问题