Damien
Damien

Reputation: 14057

jQuery Deferreds and Managing the Order of Code Execution

I have been trying to understand the benefits of jQuery's Deferred functionality. If I understand correctly Deferred's doesn't offer an alternative to callbacks but rather offers better management of callbacks? If I am writing a method and I want to be sure that it has finished executing before running another task I would still need a callback to set the deferred.resolve? Here is a code example to illustrate what I think is correct:

This is the parent function. I want to ensure 'AddItemsToList' has completed before I select the default. (This isn't a real function, just an example).

function PopulateListAndSelectDefault(list,default)
{
   var resultObject = AddItemsToList($('#myList'), list);

   successObject.Success(function(){
      SelectItemInList($('#myList'), default);
   });
}

This would be the incorrect way to write the 'AddItemsToList' function:

function AddItemsToList (jquerySelectList,items)
{
   var result= $.Deferred();
   $.each(items, function (i, _property) 
   {
      if (CheckElementIsSelectList(_property.Value)) 
      {
          jQueryListItem.append($("<option></option>").attr("value", _property.value).text(_property.DisplayText)); //Add Item
      }
   }
   result.resolve;
   return result;      
}

Instead, the correct way, would be to continue to use a callback but this time only resolve the deferred object so that I can attach futher success/failure methods later down the line if I so wished?

Have I understood correctly? What would be the correct way to write the code above or have I completely misunderstood the fundamentals? Thanks in advance.

Upvotes: 1

Views: 476

Answers (1)

Arnaud Le Blanc
Arnaud Le Blanc

Reputation: 99921

This is most useful for asynchronous functions. This is a utility class for managing callbacks.

jQuery.Deferred() is a chainable utility object that can register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.

   

jQuery.Deferred() provides flexible ways to provide multiple callbacks, and these callbacks can be invoked regardless of whether the original callback dispatch has already occurred.

The correct use of $.Deferred, in an asynchronous function, is to return a promise, and resolve the Deferred once the asynchronous operation has been done.

Pass any value (maybe the result of the function) to .resolve() and the registered callbacks will receive that value.

Example:

function getSomething() {
    var deferred = new $.Deferred;
    $.get('/get-something', function(data) {
        deferred.resolve(data);
    });
    return deferred.promise();
}

myAsynchronousFunction().done(function(data) {
    // ...
});

In this case this is equivalent to:

function getSomething(callback) {
    $.get('/get-something', function(data) {
        callback(data);
    });
}

myAsynchronousFunction(function(data) {
    // ...
});

Upvotes: 1

Related Questions