【问题标题】:How to correctly code a recursive jquery promise如何正确编码递归 jquery 承诺
【发布时间】:2015-12-19 03:34:18
【问题描述】:

请原谅我重复一个已经非常问的问题,但到目前为止我所看到的一切对我来说似乎都不是递归的,或者没有映射到我们正在做的事情,并且 promises 和 deferred 的主题似乎对我来说非常复杂。

我有一个“主题树”,它在用户展开节点时异步构建。该主题是使用 API 端点构建的,该端点在单击主题树节点上的 (+) 按钮时返回节点的子节点。

当用户单击按钮时,我尝试使用如下所示的方法递归加载主题树元素:

function getAssociatedTopics(){
    $.get('/topics/curriculum-associations', {guids: [...]})
    .then(function(data){

        //Process the topic information here
        var topicId = /* some processing */;

        //Get ancestors of each topic returned
        $.get('/topics/getAncestors', {of: topicId})
        .then(function(data){

            //Process the topic information here
            var topicId = /* some processing */;

            //Get ancestors of each topic returned
            //Rinse repeat as long as we find children of each topic found


        });

    }).then(function(){

        //Expand the nodes
        //Select the nodes

    });
}

所以这就是它应该的样子,但我完全没有阅读文档以确保我的东西以正确的顺序执行......我们现在遇到的这个结构的大问题是我的节点都加载以并发的方式,然后擦除选定的节点,随时打开和关闭节点,选择结束时超级混乱。

我不想要对 Promise 的深入解释,也不想要一个完整的解决方案,而是一个大致的想法如何实现这一点。

【问题讨论】:

  • 您要展开节点子树吗?还是只是第一个孩子?
  • 你说“当用户点击按钮时”,这个按钮是主题树节点上的(+)按钮,还是其他按钮?因为您您有“一个返回节点子节点的 API 端点”,但您还没有显示任何清楚地做到这一点的东西(除非那是 /topics/curriculum-associations 所做的)。
  • 另外,代码说获取返回的每个主题的祖先,这让我相信有一个我们没有看到的循环。一个可以很好地确定答案正确性的循环......
  • “扩展节点”到底是什么意思?加载单击节点的直接子节点,还是扩展所有节点的整个树?如果你说的是前者,那你为什么需要递归加载呢?
  • 令人困惑,你确定你不是在尝试做类似的事情 -> jsfiddle.net/adeneo/st5fz0h1

标签: javascript jquery promise


【解决方案1】:

首先,获取所需内容的复杂性应该在服务器而不是客户端上处理。从客户端发出数百个 HTTP 请求是等待发生的性能灾难。

现在你会怎么做,两个重要的事实:

  • Promises 通过使用 返回值 起作用。 $.get 返回值的承诺 - 这就是为什么你可以 then 关闭它,但你也可以将它返回到外部。
  • 如果您从then 处理程序返回一个promise,则从then 返回的promise 将首先等待内部promise 解决。

以下是说明这两点的示例:

$.get("/api").then(function(data) {
    return $.get("/api2/" + data.id);
}).then(function(data2) {
    // because of point #1, we get the data of the inner call here.
});

现在,针对您的实际问题:

function getAssociatedTopics(guids) {
    // note the `return` here so it can be chained from outside 
    return $.get('/topics/curriculum-associations', {guids: guids})
    .then(function(data){
        var topicId = someProcessing(data);
        // note we return here. I assume this get returns guids. 
        return $.get('/topics/getAncestors', {of: topicId})
    }).then(function (guids) { // this anonymous function can be inlined
        if(guids.length === 0) return; // stop condition
        return getAssociatedTopics(guids); // note the recursive call, remember point #2.
    });
}
getAssociatedTopics(initial).then(function(){
    // all done
});

如果您需要所有调用的结果,可以将其链接起来,或者您可以在最后一个之前的 then 中推送到闭包变量数组,并在 all done 处理程序中访问它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2014-02-04
    • 1970-01-01
    • 2016-12-02
    • 2016-12-23
    • 2017-03-26
    • 2017-01-31
    相关资源
    最近更新 更多