javascriptjqueryjquery-deferredpromisejquery-chaining

Chain of Jquery Promises


I have a simple chain of events:

  1. Get Columns from a metaData table (async)
  2. load selected columns (async)
  3. render list

I used to just the chain these functions, each calling the next when it had completed. However, its not very obvious what's going (calling getColumnsFromMeta results in the view being populated). So in the interest of clarity and code re-use I'd like to refactor these using JQuery Promises. I have used promises before. But how do I chain more than two? getColumnsFromMeta ().then(loadSourceFromDatabase /*some arguments*/) //.then(renderList)?;

Here's an example of the getColumnsFromMeta:

var getColumnsFromMeta = function(id)
{
    var sql,
        dfd;

    dfd = $.Deferred();

    var onSuccess = function(tx, result)
    {
        var columns = [];

        for (var i = 0; i < result.rows.length; i++) 
        {
            columns.push(result.rows.item(i).Column);
        }

        dfd.resolve(columns);
    };

    var onError = function(tx, error)
    {
        dfd.reject(error);
    };

    sql = "SELECT Column FROM Meta WHERE id = ?";

    database.query(sql, [id], onSuccess, onError);

    return dfd.promise();
};

Solution

  • It should be something like:

    function getColumnsFromMeta()
    {
        var d = $.Deferred();
    
        // retrieve data in async manner and perform
        // d.resolve(columns);
    
        return d.promise();
    }
    
    function loadSelectedColumns(columns)
    {
        var d = $.Deferred();
    
        // retrieve data in async manner and perform
        // d.resolve(data);
    
        return d.promise();
    }
    
    function render(data)
    {
        // render your data
    }
    
    getColumnsFromMeta().pipe(loadSelectedColumns).pipe(render);
    

    http://jsfiddle.net/zerkms/xYDbm/1/ - here is a working sample

    http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/ -- this is the article I really like about promises