Javascript 如何正确编写递归jquery承诺
如果我在重复一个已经被问到的问题,请原谅,但迄今为止我所看到的一切对我来说似乎都不是递归的,或者与我们正在做的事情不一致,承诺和延迟的主题对我来说似乎非常复杂 我有一个“主题树”,在用户扩展节点时异步构建。此主题使用API端点构建,该端点在单击主题树节点上的(+)按钮时返回节点的子节点 当用户单击按钮时,我尝试使用如下方法递归加载主题树元素:Javascript 如何正确编写递归jquery承诺,javascript,jquery,promise,Javascript,Jquery,Promise,如果我在重复一个已经被问到的问题,请原谅,但迄今为止我所看到的一切对我来说似乎都不是递归的,或者与我们正在做的事情不一致,承诺和延迟的主题对我来说似乎非常复杂 我有一个“主题树”,在用户扩展节点时异步构建。此主题使用API端点构建,该端点在单击主题树节点上的(+)按钮时返回节点的子节点 当用户单击按钮时,我尝试使用如下方法递归加载主题树元素: function getAssociatedTopics(){ $.get('/topics/curriculum-associations',
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
所做的)。此外,代码说返回每个主题的祖先,这让我相信有一个循环我们没有看到。一个可以很好地确定答案正确性的循环……你所说的“扩展节点”到底是什么意思?加载所单击节点的直接子节点,还是展开所有节点的整个树?如果您指的是前者,那么为什么需要递归加载?令人困惑的是,您肯定没有尝试执行类似->