Javascript 等待递归函数完成
我有一个递归Javascript函数,它从一个Wikipedia页面获取链接,跟踪它们,然后获取所有这些链接(重复指定次数) 它调用自己未知的次数来构造一个已知深度的对象。当它完成时,我想输出对象。当前,对象立即输出,并且为空,这意味着函数显然没有等待所有递归调用完成 正如您所看到的,我试图使用回调,但我的假设是错误的。我做错了什么,我该怎么做?我想我还没有发现其他一些错误;我对Javascript比较陌生Javascript 等待递归函数完成,javascript,function,recursion,Javascript,Function,Recursion,我有一个递归Javascript函数,它从一个Wikipedia页面获取链接,跟踪它们,然后获取所有这些链接(重复指定次数) 它调用自己未知的次数来构造一个已知深度的对象。当它完成时,我想输出对象。当前,对象立即输出,并且为空,这意味着函数显然没有等待所有递归调用完成 正如您所看到的,我试图使用回调,但我的假设是错误的。我做错了什么,我该怎么做?我想我还没有发现其他一些错误;我对Javascript比较陌生 $(document).ready(function () { pageLinks[
$(document).ready(function ()
{
pageLinks[START_PAGE] = {};
//Get initial pages
links = getLinks(START_PAGE, 0, printLinks));
});
function printLinks()
{
console.log(links);
}
function getLinks(currentPage, level, callback)
{
visitedPages.push(currentPage)
var pageLinks = {}
var data = $.getJSON(URL_BEGIN + currentPage + URL_END, function(data)
{
var pages = data.query.pages;
for(var page in pages)
{
pageContentObj = pages[page].revisions[0];
for(var key in pageContentObj) if(pageContentObj[key].length > 100)
{
var pageContent = pageContentObj[key];
//Get links
hyperlinks = getFromBetween.get(pageContent,"[[","]]");
for(var link in hyperlinks)
{
link = hyperlinks[link].split("|")[0]; //Remove friendly name
link = link.replaceAll(" ", "%20");
//Add to pagelist object
prefix = link.split(":")[0];
if(prefix != "Category" && prefix != "File" && prefix != "wikipedia")
if(level < ITERATIONS && !visitedPages.includes(arguments, link))
{
console.log(level + ": " + link)
pageLinks[link] = getLinks(link, level+1, callback); //===Recursive call===
}
}
}
}
});
if(level == 0 && callback) callback();
return pageLinks;
}
$(文档).ready(函数()
{
页面链接[开始页面]={};
//获取首页
links=getLinks(开始页面,0,打印链接));
});
函数printLinks()
{
控制台日志(链接);
}
函数getLinks(当前页面、级别、回调)
{
visitedPages.push(当前页面)
var pageLinks={}
var data=$.getJSON(URL\u BEGIN+currentPage+URL\u END,函数(数据)
{
var pages=data.query.pages;
for(页面中的var页面)
{
pageContentObj=页面[page]。修订[0];
对于(pageContentObj中的var键)如果(pageContentObj[key]。长度>100)
{
var pageContent=pageContentObj[key];
//获取链接
hyperlinks=getFromBetween.get(pageContent,“[[”,“]]”);
for(超链接中的变量链接)
{
link=超链接[link]。拆分(“|”)[0];//删除友好名称
link=link.replaceAll(“,“%20”);
//添加到页面列表对象
前缀=link.split(“:”[0];
如果(前缀!=“类别”&&prefix!=“文件”&&prefix!=“维基百科”)
if(级别
感谢您的帮助,提前谢谢
**编辑:**链接:递归调用需要如下所示:
var counter = 0;
//the big for loop
counter++;
getLinks(link, level + 1, function(res) {
for (var key in res) { //with an array it would be concat...
pageLinks[key] = res[key];
}
counter--;
if (counter == 0 && callback) callback(pageLinks); //callback if all callbacks called
});
还要删除这个奇怪的代码:
if(level == 0 && callback) callback();
不,你可以做:
getLinks(START_PAGE, 0, console.log);
这很有可能把维基百科下载到你的服务器上。您确定要对服务器执行此操作并且Wikipedia允许您执行此操作吗?将
Promise.all()
,Array.prototype.map()
替换为for..in
循环中的。也请看,我只是在我的家用电脑上运行它作为一个实验,所以最大38Mb/s-我已经测试了几次,维基百科似乎运行良好…所以你打算打印出来@mplungjan谢谢你的帮助,不过我现在没有输出对象。您是否有意使用key
引用现有变量,或者是否应该重命名该变量?@JakeStanger key在for-in循环中定义。如果存在另一个名为key的var,则应重命名其中一个……我想情况就是这样。但我仍然没有得到任何输出。让我上传到Github,我会用链接编辑我的原始帖子…@JakeStanger ok。但是我会离开一段时间,也许明天会有反应。没关系,我不着急。这只是我业余时间的一个小实验。谢谢你的帮助。