Jquery 承诺链
Posted
技术标签:
【中文标题】Jquery 承诺链【英文标题】:Chain of Jquery Promises 【发布时间】:2012-07-17 09:13:13 【问题描述】:我有一个简单的事件链:
-
从元数据表中获取列(异步)
加载选定的列(异步)
渲染列表
我过去只是链接这些函数,每个函数在完成后调用下一个函数。但是,发生了什么并不是很明显(调用getColumnsFromMeta
会导致视图被填充)。所以为了清晰和代码重用,我想用JQuery
Promises
重构这些。我以前使用过承诺。但是我如何链接两个以上? 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();
;
【问题讨论】:
【参考方案1】:应该是这样的:
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 的文章
【讨论】:
感谢您的快速回复,效果很好!感谢您的文章,它看起来不错。作为一个额外的问题:是否可以将 .done/.always 等链接到不同阶段的管道? @CrimsonChin:是的。 PS:等一下,jsfiddle马上就搞定了 @CrimsonChin:是的,你可以使用其中任何一个,只要pipe()
也返回延迟。 PS:我添加了jsfiddle示例
@pcv:我提出这个答案还不到一年前
使用 jQuery 1.8 及更高版本,您可以将 'pipe' 替换为 'then',正如 @pcv 正确提到的那样【参考方案2】:
经过一番思考,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)
);
【讨论】:
以上是关于Jquery 承诺链的主要内容,如果未能解决你的问题,请参考以下文章