Javascript Jquery承诺链
我有一个简单的事件链: 从元数据表异步获取列 异步加载选定列 渲染列表 我习惯于将这些函数链接起来,每个函数在完成后调用下一个函数。然而,调用getColumnsFromMeta的结果并不十分明显,因为它会导致视图被填充。因此,为了清晰和代码重用,我想使用JQuery承诺重构这些。我以前用过承诺。但我如何将两个以上的链接链接起来?getColumnsFromMeta.thenloadSourceFromDatabase/*一些参数*///.thenrenderList 下面是getColumnsFromMeta的一个示例:Javascript Jquery承诺链,javascript,jquery,jquery-deferred,promise,jquery-chaining,Javascript,Jquery,Jquery Deferred,Promise,Jquery Chaining,我有一个简单的事件链: 从元数据表异步获取列 异步加载选定列 渲染列表 我习惯于将这些函数链接起来,每个函数在完成后调用下一个函数。然而,调用getColumnsFromMeta的结果并不十分明显,因为它会导致视图被填充。因此,为了清晰和代码重用,我想使用JQuery承诺重构这些。我以前用过承诺。但我如何将两个以上的链接链接起来?getColumnsFromMeta.thenloadSourceFromDatabase/*一些参数*///.thenrenderList 下面是getColumns
应该是这样的:
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);
-这是一个工作样本
-这是一篇我非常喜欢的关于承诺的文章经过思考,虫族的回答帮助了我。我将在这里发布我所做的,以防一个完整上下文的示例有帮助
/**
* 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)
});
感谢您的快速回复,它工作得很好!谢谢你的文章,看起来不错。另外一个问题是:是否可以在不同的阶段将.done/.always等链接到管道上?@CrimsonChin:是的。PS:给我一秒钟,JSFIDLE将在一个小时内完成moment@CrimsonChin:是的,只要管道返回延迟,您可以使用其中任何一个。PS:我添加了JSFIDLEexample@pcv:不到一年前,当我用jQuery 1.8和更高版本来回答这个问题时,你可以用@pcv正确提到的“then”来代替“pipe”
/**
* 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)
});