Pass in an array of Deferreds to $.when()

后端 未结 9 1228
伪装坚强ぢ
伪装坚强ぢ 2020-11-21 22:20

Here\'s an contrived example of what\'s going on: http://jsfiddle.net/adamjford/YNGcm/20/

HTML:

Click me!
&l
9条回答
  •  隐瞒了意图╮
    2020-11-21 22:33

    The workarounds above (thanks!) don't properly address the problem of getting back the objects provided to the deferred's resolve() method because jQuery calls the done() and fail() callbacks with individual parameters, not an array. That means we have to use the arguments pseudo-array to get all the resolved/rejected objects returned by the array of deferreds, which is ugly:

    $.when.apply($,deferreds).then(function() {
         var objects=arguments; // The array of resolved objects as a pseudo-array
         ...
    };
    

    Since we passed in an array of deferreds, it would be nice to get back an array of results. It would also be nice to get back an actual array instead of a pseudo-array so we can use methods like Array.sort().

    Here is a solution inspired by when.js's when.all() method that addresses these problems:

    // Put somewhere in your scripting environment
    if (typeof jQuery.when.all === 'undefined') {
        jQuery.when.all = function (deferreds) {
            return $.Deferred(function (def) {
                $.when.apply(jQuery, deferreds).then(
                    function () {
                        def.resolveWith(this, [Array.prototype.slice.call(arguments)]);
                    },
                    function () {
                        def.rejectWith(this, [Array.prototype.slice.call(arguments)]);
                    });
            });
        }
    }
    

    Now you can simply pass in an array of deferreds/promises and get back an array of resolved/rejected objects in your callback, like so:

    $.when.all(deferreds).then(function(objects) {
        console.log("Resolved objects:", objects);
    });
    

提交回复
热议问题