javascript Jquery 承诺链
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11539605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chain of Jquery Promises
提问by Jon Wells
I have a simple chain of events:
我有一个简单的事件链:
- Get Columns from a metaData table (async)
- load selected columns (async)
- 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)?;
我曾经只是将这些函数链接起来,每个函数在完成后调用下一个函数。但是,发生了什么并不是很明显(getColumnsFromMeta
在填充的视图中调用结果)。因此,为了清晰和代码重用,我想使用JQuery
Promises
. 我以前使用过承诺。但是我如何链接两个以上?getColumnsFromMeta ().then(loadSourceFromDatabase /*some arguments*/) //.then(renderList)?;
Here's an example of the getColumnsFromMeta
:
下面是一个例子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();
};
回答by zerkms
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://jsfiddle.net/zerkms/xYDbm/1/- 这是一个工作示例
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/-- this is the article I really like about promises
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/——这是我非常喜欢关于承诺的文章
回答by Dustin Getz
zerkms's reply helped me after some thought. I'm going to post what I did here in case an example with full context is helpful.
经过一番思考,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)
});