пятница, 19 октября 2012 г.

Async.js vs. Jquery Deferred

Intro

Do you know Async.js? It is a javascript framework helping deal with async functions. Let's imagine we want to render some html template:

compare_two_items_html = function(item_1, item_2) {
    return _.template("item #<%= item_1.id %>: <%= item_1.price %> USD vs. item #<%= item_2.id %>: <%= item_2.price %> USD");
}​

And we have function of loading item:

load_item = function(id, callback) {
    $.getJSON("/items/" + id, callback);
};

To render this, we should write something like that:

load_item(5, function(item_1) {
    load_item(12, function(item_2) {
        $("#compare_items").html(compare_two_items_html(item_1, item_2));
    });
});

A little bit messy. Imagine if we had more then 2 dependencies.

Async.js

Parallel

With Async.js we could have code like this:

async.parallel([
    function(callback) {
    load_item(5, function(item) {
        callback(null, item);
    });},
    function(callback) {
    load_item(12, function(item) {
        callback(null, item);
    });}], function(err, results) {
    $("#compare_items").html(compare_two_items_html(results[0], results[1]));
});

Now these 2 requests are made in parallel!

Waterfall

What if we could not make the second request, before first is finished? We should use async.waterfall:

async.waterfall([
    function(callback) {
    load_user(8, function(user) {
        callback(null, user);
    });},
    function(user, callback) {
    load_user_items(user, function(items) {
        callback(null, user, items);
    });},
    function(user, items, callback) {
    $("#user_items").html(render_user_and_items(user, items));}
]);

jQuery.Deferred

Have you ever heard about jQuery.Deferred? It is inside your jQuery right now! All ajax methods return $.Deferred object. So, lets modify our load_item function:

load_item = function(id) {
    return $.getJSON("/items/" + id);
};

Parallel

$.when(load_item(5), load_item(12)).then(function(item_1, item_2) {
    $("#compare_items").html(compare_two_items_html(item_1, item_2));
});

Waterfall

load_user(8).pipe(function(user) {
    return $.Deferred(function() {
        var deferred = this;
        load_user_items(user.id).then(function() {
            deferred.resolve(user, items)
        });
    });
}).then(function(items) {
    $("#user_items").html(render_user_and_items(user, items));
});​

Looks not very nice :) If You know, how to make it prettier, let me know!

Good luck!


Комментарии

технология комментирования HyperComments


2008–2014 © Сергей Удалов Реклама Система Orphus