<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Bitovi Blog - UX and UI design, JavaScript and Front-end development
Loading

Bitovi |

Deferreds and 3.1

Deferreds and 3.1

Brian Moschel

Brian Moschel

Twitter Reddit

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?