Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Deferred/Promise Design Patterns and use cases

My question is quite general and some related questions can be found on SO, but none of those really are what I am looking for.

I have been reading up on/toying with the jQuery Deferred object and I see it is used a lot inside the library itself to handle ajax requests and animation etc. I understand the general functionality and think it has proven to be very useful in some situations. The jQuery library solves some problems quite elegantly using this concept.

Now my question is: I think it would be very useful to have an overview of distinct problem/solution scenarios that can be solved elegantly and robustly using the Deferred object.

In which situations is a solution using jQuery Deferred called for? Which general patterns in javascript software design can be distinguished that can be solved most elegantly using jQuery Deferred functionality? I'm aiming to compile a list of quite general patterns (as opposed to very specific examples), in the spirit of the gang of four design patterns every OO analyst knows about.

With such a list in the back of the head, when designing jQuery solutions it should become second nature to take advantage of these deferred patterns in just the same way the bridge, factory, ... patterns already help us to design flexible and robust solutions without having to re-invent the wheel every time.

like image 986
Asciiom Avatar asked Aug 28 '12 13:08

Asciiom


2 Answers

Asynchronous Tasks broadly fall into 5 different problem domains.

Network/Local data requests

Probably the most common, and well covered by Fabrizio Calderan's answer. In these cases we have to handle at least 2 outcomes, and depending on granularity (various types of success or errors for a request), and then act on them.

Deferred/Promises allows us to chain, or parallelise requests, or hybrids of both to achieve the resource loading we need for our task. For example, we can wait for a range of requests to complete before we then load some more, or do something else based on those outcomes.

Animation

Chaining/Parallel animated sequences, are more easy to implement, and maintain. Conditional steps based on different outcomes (when accounting for user interaction or a random factor.) are also easy to implement and maintain.

(pseudo) Modal User Interaction

True modal operation isn't possible in the browser, and presenting dialogs, wizards etc. requires asynchronous operations provided by Deferred/Promises to act on resolved outcomes, (success, activities, options, cancellation etc.) before cleaning up the display (also simplified, as mentioned already) and resuming normal operation. Deferred/Promises allow you to act on those outcomes in a relatively simple declarative fashion.

Effectively this combines user interaction with animation/display sequences.

Hardware availability/responses

Mobile device(s) availability (for example through PhoneGap) needs to be guaranteed before calling them for services, and in many cases, provide response asynchronously. Using Deferred /Promises simplifies and improves the code managing these device interactions.

Software component activity

SQLLite specifically, provides it's responses to JS requests asynchronously, and so doing complex query interactions, is far simpler than it would be using callbacks.

In theory this applies to any auxillary software component which provides asynchronous responses.

One more thing...

This is one of the best articles I've read on Deferred/Promises, I recommend reading it for some proper in-depth examples and explanations.

  • http://sitr.us/2012/07/31/promise-pipelines-in-javascript.html

tl;dr

The big benefit of Deferred/Promises is that they make solutions for several domains much easier to conceive in the first place and maintain afterwards. In some cases they simplify them so much, that had they been attempted using callbacks and convoluted outcome checking, many fully grown adults (and possibly a number of small children)

...would go from this...

We're on a boat, and we're using Deferred/Promises

To this...

callbacks are a nightmare

If a solution requires chaining, waiting for the outcome of one or more processes to resolve, or any combination of these, Deferred/Promises will save you frustration and anguish, and will do the same for anyone who inherits your code.

Now go out and prove me wrong by committing horrible abuses. No, really, don't do that. Write nice clean, maintainable code.

Disclaimer: Using Deferred/Promises in your code may not feel like you are "on a boat", but it will feel way better than a soup made of callbacks

like image 108
6 revs Avatar answered Sep 28 '22 15:09

6 revs


In which situations is a solution using jQuery Deferred called for

I think that as a thumb rule, every time you have both

  1. one or more asynchronous tasks
  2. some related callbacks depending on the success/fail of those task

you can try to refactor your code in terms of deferred objects and promises. Most common scenarios in which deferred objects could be used at best involve

  • An Ajax request and callback/s (a single request, parallel or chained requests)
  • An asynchronous loading of assets and actions to perform at load event (e.g. an image preloader like this one: https://gist.github.com/958683)
  • A callback to execute after complete of an animation or a lot of sequential animations which would require a lot of nested scopes: this can be easily achieved just chaining a promise() method to the animate() method so to return a promise to handle with done() callback (to be honest I cannot really figure out how an animation can fail)

hope this hint could be useful in some way.

like image 20
Fabrizio Calderan Avatar answered Sep 28 '22 15:09

Fabrizio Calderan