Chain of Jquery Promises

Chain of Jquery Promises

本文关键字:Promises Jquery of Chain      更新时间:2023-10-31

我有一个简单的事件链:

  1. 从元数据表中获取列(异步)
  2. 加载选定列(异步)
  3. 渲染列表

我过去只是把这些函数串起来,每个函数都在完成后调用下一个函数。然而,发生了什么并不十分明显(调用getColumnsFromMeta会导致视图被填充)。因此,为了清晰和代码重用,我想使用JQueryPromises重构它们。我以前用过承诺。但是,我如何链两个以上?getColumnsFromMeta ().then(loadSourceFromDatabase /*some arguments*/) //.then(renderList)?;

以下是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();
};

它应该类似于:

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/-这是的工作样本

http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/——这是我非常喜欢的关于promise 的文章

经过思考,zerkms的回复帮助了我。我将在这里发布我所做的事情,以防一个完整上下文的例子有帮助。
/**
 * takes a list of componentIDs to load, relative to componentRoot
 * returns a promise to the map of (ComponentID -> componentCfg)
 */
function asyncLoadComponents (componentRoot, components) {
    var componentCfgs = {};
    function asyncLoadComponentCfg(component) {
        var url = _.sprintf("%s/%s", componentRoot, component);
        var promise = util.getJSON(url);
        promise.done(function(data) {
            componentCfgs[component] = data;
        });
        return promise;
    }
    var promises = _.map(components, asyncLoadComponentCfg);
    var flattenedPromise = $.when.apply(null, promises);
    var componentCfgPromise = flattenedPromise.pipe(function() {
        // componentCfgs is loaded now
        return $.Deferred().resolve(componentCfgs).promise();
    });
    return componentCfgPromise;
}

var locale = 'en-US';
var componentRoot = '/api/components';
var components = ['facets', 'header', 'DocumentList'];
$.when(asyncLoadComponents(componentRoot, components)).done(function(componentCfgs) {
    buildDocumentListPage(locale, componentCfgs)
});