Javascript 等待递归函数完成

Javascript 等待递归函数完成,javascript,function,recursion,Javascript,Function,Recursion,我有一个递归Javascript函数,它从一个Wikipedia页面获取链接,跟踪它们,然后获取所有这些链接(重复指定次数) 它调用自己未知的次数来构造一个已知深度的对象。当它完成时,我想输出对象。当前,对象立即输出,并且为空,这意味着函数显然没有等待所有递归调用完成 正如您所看到的,我试图使用回调,但我的假设是错误的。我做错了什么,我该怎么做?我想我还没有发现其他一些错误;我对Javascript比较陌生 $(document).ready(function () { pageLinks[

我有一个递归Javascript函数,它从一个Wikipedia页面获取链接,跟踪它们,然后获取所有这些链接(重复指定次数)

它调用自己未知的次数来构造一个已知深度的对象。当它完成时,我想输出对象。当前,对象立即输出,并且为空,这意味着函数显然没有等待所有递归调用完成

正如您所看到的,我试图使用回调,但我的假设是错误的。我做错了什么,我该怎么做?我想我还没有发现其他一些错误;我对Javascript比较陌生

$(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。但是我会离开一段时间,也许明天会有反应。没关系,我不着急。这只是我业余时间的一个小实验。谢谢你的帮助。