Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.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_Promise - Fatal编程技术网

Javascript 如何正确编写递归jquery承诺

Javascript 如何正确编写递归jquery承诺,javascript,jquery,promise,Javascript,Jquery,Promise,如果我在重复一个已经被问到的问题,请原谅,但迄今为止我所看到的一切对我来说似乎都不是递归的,或者与我们正在做的事情不一致,承诺和延迟的主题对我来说似乎非常复杂 我有一个“主题树”,在用户扩展节点时异步构建。此主题使用API端点构建,该端点在单击主题树节点上的(+)按钮时返回节点的子节点 当用户单击按钮时,我尝试使用如下方法递归加载主题树元素: function getAssociatedTopics(){ $.get('/topics/curriculum-associations',

如果我在重复一个已经被问到的问题,请原谅,但迄今为止我所看到的一切对我来说似乎都不是递归的,或者与我们正在做的事情不一致,承诺和延迟的主题对我来说似乎非常复杂

我有一个“主题树”,在用户扩展节点时异步构建。此主题使用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

    });
}
这就是它应该看起来的样子,但是我完全没有阅读文档来确保我的东西按正确的顺序执行。。。这个结构现在面临的一个大问题是,我的节点都以并发方式加载,然后删除所选节点,随时打开和关闭节点,选择结果会非常混乱


我不想要对承诺进行深入的解释,也不想要一个完整的解决方案,而是想要一个如何实现这一点的总体思路。

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

现在让我们来看看如何做到这一点,两个重要的事实:

  • 承诺通过使用返回值来工作
    $.get
    返回对值的承诺-这就是为什么您可以
    然后
    关闭它,但也可以将它返回到外部
  • 如果从
    然后从
    处理程序返回承诺,则承诺从
    返回,然后
    本身将等待内部承诺首先解析
    
下面是一个示例,说明了两点:

$.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处理程序中访问它

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