Skip to content

Instantly share code, notes, and snippets.

@moschel
Forked from justinbmeyer/deferreds.md
Created October 12, 2011 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moschel/1282794 to your computer and use it in GitHub Desktop.
Save moschel/1282794 to your computer and use it in GitHub Desktop.
Deferreds and 3.1

3.1 Backlog - Deferreds

jQuery 1.6 brought Deferred support. They are a great feature that promise to make a lot of asynchronous functionality easier to write and manage. But many people struggle with uses other than 'waiting for a bunch of Ajax requests to complete'. For JavaScriptMVC 3.1, we identified an extremely common but annoying practice that becomes a one-liner with deferreds: loading data and a template and rendering the result into an element.

Templates Consume Deferreds

Here's rendering templates looks like in 3.1:

$('#todos').html('temps/todos.ejs', $.get('/todos',{},'json') );

This will make two parallel ajax requests. One request is made for the template at temps/todos.ejs:

<% for(var i =0; i < this.length; i++) { %>
  <li><%= this[i].name %></li>
<% } %>

The second request for /todos might respond with a JSON array:

[
    {"id" : 1, "name": "Take out the Trash"},
    {"id" : 2, "name": "Do the Laundry"}
]

When both have been loaded, the template is rendered with the todos data. The resulting HTML is placed in the #todos element.

This is fab fast! The AJAX and template request are made in parallel and rendered when both are complete. Before deferreds, this was a lot uglier:

var template,
	data,
    done = function(){ 
       if( template && data ) { 
         var html = new EJS({text: template})
                                .render(data);
         $('#todos').html( html )
       }
    }
$.get('temps/todos.ejs', function(text){
  template = text;
  done();
},'text')
$.get('/todos',{}, function(json){
  data = json
  done();
},'json')

Models Return Deferreds

Model AJAX functions now return deferreds. Creating models like:

$.Model('User',{
  findAll: '/users'
},{});

$.Model('Todo',{
  findAll: '/todos'
},{})

Lets you request todos and users and get back a deferred that can be used in functions that accept deferreds like $.when:

$.when( User.findAll(), 
        Todo.findAll() )

Or $.View:

$('#content').html('temps/content.ejs',{
  users : User.findAll(),
  todos: Todo.findAll()
})

Conclusion

Despite using templates, this is still 'waiting for a bunch of Ajax requests to complete'. Does anyone have other good uses for deferreds?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment