Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Jquery承诺链_Javascript_Jquery_Jquery Deferred_Promise_Jquery Chaining - Fatal编程技术网

Javascript Jquery承诺链

Javascript Jquery承诺链,javascript,jquery,jquery-deferred,promise,jquery-chaining,Javascript,Jquery,Jquery Deferred,Promise,Jquery Chaining,我有一个简单的事件链: 从元数据表异步获取列 异步加载选定列 渲染列表 我习惯于将这些函数链接起来,每个函数在完成后调用下一个函数。然而,调用getColumnsFromMeta的结果并不十分明显,因为它会导致视图被填充。因此,为了清晰和代码重用,我想使用JQuery承诺重构这些。我以前用过承诺。但我如何将两个以上的链接链接起来?getColumnsFromMeta.thenloadSourceFromDatabase/*一些参数*///.thenrenderList 下面是getColumns

我有一个简单的事件链:

从元数据表异步获取列 异步加载选定列 渲染列表 我习惯于将这些函数链接起来,每个函数在完成后调用下一个函数。然而,调用getColumnsFromMeta的结果并不十分明显,因为它会导致视图被填充。因此,为了清晰和代码重用,我想使用JQuery承诺重构这些。我以前用过承诺。但我如何将两个以上的链接链接起来?getColumnsFromMeta.thenloadSourceFromDatabase/*一些参数*///.thenrenderList

下面是getColumnsFromMeta的一个示例:


应该是这样的:

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)
});