Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery deferreds and promises - .then() vs .done()

I've been reading about jQuery deferreds and promises and I can't see the difference between using .then() & .done() for successful callbacks. I know Eric Hynds mentions that .done() and .success() map to the same functionality but I'm guessing so does .then() as all the callbacks are all invoked on a completion of a successful operation.

Can anyone please enlighten me to the correct usage?

like image 419
screenm0nkey Avatar asked Mar 25 '11 18:03

screenm0nkey


People also ask

What is done function in jQuery?

done() method in jQuery is used to add handlers which are to be called when the deferred object is resolved. Parameters: Callbacks: This parameter specifies a function, or array of functions, which are called when the Deferred is resolved.

What is done in promise?

A few promise libraries have a . done() method whose main purpose is to catch and rethrow any errors that were not handled, so that they show up in the console (in browsers) or crash the process in Node.

How use jQuery Deferred and promise?

If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred. promise() so other code can register callbacks or inspect the current state. For more information, see the documentation for Deferred object.

What is jQuery Deferred and promise object?

A promise is, as the name says, a promise about a future value. Together with the Promise object , Deferred represents the jQuery implementation of promises. You can attach callbacks to it to get that value. It possesses a subset of the methods of the Deferred object : always(), done(), fail(), state(), and then().


2 Answers

The callbacks attached to done() will be fired when the deferred is resolved. The callbacks attached to fail() will be fired when the deferred is rejected.

Prior to jQuery 1.8, then() was just syntactic sugar:

promise.then( doneCallback, failCallback ) // was equivalent to promise.done( doneCallback ).fail( failCallback ) 

As of 1.8, then() is an alias for pipe() and returns a new promise, see here for more information on pipe().

success() and error() are only available on the jqXHR object returned by a call to ajax(). They are simple aliases for done() and fail() respectively:

jqXHR.done === jqXHR.success jqXHR.fail === jqXHR.error 

Also, done() is not limited to a single callback and will filter out non-functions (though there is a bug with strings in version 1.8 that should be fixed in 1.8.1):

// this will add fn1 to 7 to the deferred's internal callback list // (true, 56 and "omg" will be ignored) promise.done( fn1, fn2, true, [ fn3, [ fn4, 56, fn5 ], "omg", fn6 ], fn7 ); 

Same goes for fail().

like image 86
Julian Aubourg Avatar answered Sep 25 '22 19:09

Julian Aubourg


There is also difference in way that return results are processed (its called chaining, done doesn't chain while then produces call chains)

promise.then(function (x) { // Suppose promise returns "abc"     console.log(x);     return 123; }).then(function (x){     console.log(x); }).then(function (x){     console.log(x) }) 

The following results will get logged:

abc 123 undefined 

While

promise.done(function (x) { // Suppose promise returns "abc"     console.log(x);     return 123; }).done(function (x){     console.log(x); }).done(function (x){     console.log(x) }) 

will get the following:

abc abc abc 

---------- Update:

Btw. I forgot to mention, if you return a Promise instead of atomic type value, the outer promise will wait until inner promise resolves:

promise.then(function (x) { // Suppose promise returns "abc"     console.log(x);     return $http.get('/some/data').then(function (result) {         console.log(result); // suppose result === "xyz"         return result;     }); }).then(function (result){     console.log(result); // result === xyz }).then(function (und){     console.log(und) // und === undefined, because of absence of return statement in above then }) 

in this way it becomes very straightforward to compose parallel or sequential asynchronous operations such as:

// Parallel http requests promise.then(function (x) { // Suppose promise returns "abc"     console.log(x);      var promise1 = $http.get('/some/data?value=xyz').then(function (result) {         console.log(result); // suppose result === "xyz"         return result;     });      var promise2 = $http.get('/some/data?value=uvm').then(function (result) {         console.log(result); // suppose result === "uvm"         return result;     });      return promise1.then(function (result1) {         return promise2.then(function (result2) {            return { result1: result1, result2: result2; }         });     }); }).then(function (result){     console.log(result); // result === { result1: 'xyz', result2: 'uvm' } }).then(function (und){     console.log(und) // und === undefined, because of absence of return statement in above then }) 

The above code issues two http requests in parallel thus making the requests complete sooner, while below those http requests are being run sequentially thus reducing server load

// Sequential http requests promise.then(function (x) { // Suppose promise returns "abc"     console.log(x);      return $http.get('/some/data?value=xyz').then(function (result1) {         console.log(result1); // suppose result1 === "xyz"         return $http.get('/some/data?value=uvm').then(function (result2) {             console.log(result2); // suppose result2 === "uvm"             return { result1: result1, result2: result2; };         });     }); }).then(function (result){     console.log(result); // result === { result1: 'xyz', result2: 'uvm' } }).then(function (und){     console.log(und) // und === undefined, because of absence of return statement in above then }) 
like image 37
Lu4 Avatar answered Sep 24 '22 19:09

Lu4