Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous JavaScript - Callbacks vs Deferred/Promise [duplicate]

Possible Duplicate:
What are the differences between Deferred, Promise and Future in Javascript?

Lately I've been making an effort to improve the quality of my JavaScript applications.

One pattern I've adopted is to use a separate "data context" object to load data for my application (previously I was doing this directly in my view models).

The following example returns data that is initialized on the client:

var mockData = (function($, undefined) {      var fruit = [         "apple",         "orange",         "banana",         "pear"         ];      var getFruit = function() {         return fruit;     };      return {         getFruit: getFruit     } })(jQuery); 

In most cases we'll be loading data from the server so we can't return an immediate response. It seems I have two options for how we handle this in our API:

  1. Using a callback
  2. Returning a promise.

Previously I'd always used the callback approach:

var getFruit = function(onFruitReady) {     onFruitReady(fruit); };  // ...  var FruitModel = function(dataContext, $) {     return {         render: function() {             dataContext.getFruit(function(fruit) {                 // do something with fruit             });         }     }; }; 

However, I can see how it's possible to end up in callback hell, especially when building complex JavaScript applications.

Then I came across the Promises design pattern. Instead of requiring the caller to supply a callback, I instead return a "promise" that can be observed:

var getFruit = function() {     return $.Deferred().resolve(fruit).promise(); };  // ... dataContext.getFruit().then(function(fruit) {     // do something with fruit }); 

I can see obvious benefits of using this pattern, especially since I can wait on multiple deferred objects which could be very useful when loading initialization data for a single page application.

However, I'm keen to understand the pros and cons of each pattern before I start to use either in anger. I'm also interested in whether this is the direction other libraries are going in. It seems to be the case with jQuery.

Here's a link to the fiddle I'm using for testing.

like image 975
Ben Foster Avatar asked Jan 02 '13 19:01

Ben Foster


People also ask

Are promises better than callbacks?

They can handle multiple asynchronous operations easily and provide better error handling than callbacks and events. In other words also, we may say that, promises are the ideal choice for handling multiple callbacks at the same time, thus avoiding the undesired callback hell situation.

Are JavaScript callbacks asynchronous?

Callbacks are not asynchronous by nature, but can be used for asynchronous purposes. In this code, you define a function fn , define a function higherOrderFunction that takes a function callback as an argument, and pass fn as a callback to higherOrderFunction .

What is the difference between a promise and a callback in the context of asynchronous code?

Callbacks are functions passed as arguments into other functions to make sure mandatory variables are available within the callback-function's scope. Promises are placeholder objects for data that's available in the future.

Are promises the same as callbacks?

A promise is a returned object where you attach callbacks, instead of passing callbacks into a function. the place where you attach the callback after a successful completion of a task is called, . then(). inside this you pass a callback through.


2 Answers

Promises also rely on callbacks behind the scene, so it's not really one vs. the other.

The benefit of callbacks is that they are easy to implement with plain JavaScript (for example in ajax calls).

Promises require an additional abstraction layer, which usually means that you'll rely on a library (not an issue in your case as you are already using jQuery). They are perfect when you deal with multiple async calls in parallel.

like image 172
Christophe Avatar answered Oct 08 '22 23:10

Christophe


From reading the jQuery docs that @Pointy linked to, it sounds like the difference is that the Deferred API allows you to specify more than one function to be called when your request completes:

As of jQuery 1.5, the error (fail), success (done), and complete (always, as of jQuery 1.6) callback hooks are first-in, first-out managed queues. This means you can assign more than one callback for each hook. See Deferred object methods, which are implemented internally for these $.ajax() callback hooks.

See also: deferred.then()

like image 43
Max Fellows Avatar answered Oct 09 '22 00:10

Max Fellows