Question

I have some idea about Deferreds and what they do but I can't understand their usage in a piece of code I am working with right now. This code is from jquery-file-upload plugin and file jquery-fileupload-ui.js:

stop: function (e) {
    var that = $(this).data('blueimp-fileupload') ||
            $(this).data('fileupload'),
        deferred = that._addFinishedDeferreds();
    $.when.apply($, that._getFinishedDeferreds())
        .done(function () {
            that._trigger('stopped', e);
        });
    that._transition($(this).find('.fileupload-progress')).done(
        function () {
            $(this).find('.progress')
                .attr('aria-valuenow', '0')
                .children().first().css('width', '0%');
            $(this).find('.progress-extended').html(' ');
            deferred.resolve();
        }
    );
},

_addFinishedDeferreds: function (deferred) {
    if (!deferred) {
        deferred = $.Deferred();
    }
    this._finishedUploads.push(deferred);
    return deferred;
},

_getFinishedDeferreds: function () {
    return this._finishedUploads;
},

In the stop method, there are two constructs that I don't understand:

1)

$.when.apply($, that._getFinishedDeferreds())
.done(function () {
    that._trigger('stopped', e);
});

2)

deferred = that._addFinishedDeferreds();
//and later in the _transition function
deferred.resolve();

The second construct repeats throughout the whole code. I can see that _addFinishedDeferreds creates a deferred (if it is not passed as an argument), adds it to _finishedUploads and that deferred is later resolved. But I am missing the meaning of all this. What is it good for? Why the code can't work without it? And I don't understand the meaning of the first construct at all. Anyone can shed some light on this?

Was it helpful?

Solution

First I assume you understand basic usage of Deferreds, including resolve() and $.when().

From my understand of this code snippet, the stop function will be called multiple times, each time a new Deferred is created and will not be resolved until the transition is completed, though I don't know what transition it is because you did not show us its code. The Deferred object here, is to signal the completion of transition, and then a stopped event is triggered.

Details

1)

$.when.apply($, that._getFinishedDeferreds())
.done(function () {
    that._trigger('stopped', e);
});

$.when.apply($, that._getFinishedDeferreds()) generates a new Deferred which is resolved after every Deferred is resolved in the array returned by _getFinishedDeferreds(). Then the callback function in done() triggers the stopped event.

2)

deferred = that._addFinishedDeferreds();
//and later in the _transition function
deferred.resolve();

Your understanding is correct. The intention of this code (if I guess correctly) is to make sure the event is not triggered until all transition is finished.

However if so there's a bug that the event trigger callback:

function () {
    that._trigger('stopped', e);
}

is attached each time stop() is called so the event may be triggered multiple times.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top