【问题标题】:Waiting for Recursive Function To Complete等待递归函数完成
【发布时间】:2017-06-22 15:02:30
【问题描述】:

我有一个递归 Javascript 函数,它从一个维基百科页面获取链接,跟随它们,然后获取所有这些链接(重复指定的次数)。

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

如您所见,我曾尝试使用回调,但我的假设不正确。我做错了什么,我该怎么做?我假设还有其他一些我没有发现的错误;我对 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;
}

任何帮助表示赞赏,在此先感谢。

**编辑:**链接:https://github.com/JakeStanger/Wikipedia-Mapper/blob/master/init.js#L53

【问题讨论】:

  • 这很有可能将维基百科吸到你的服务器上。您确定要对您的服务器执行此操作并被 Wikipedia 允许执行此操作吗?
  • Promise.all()Array.prototype.map() 替换for..in 循环。另见multiple, sequential fetch() Promise
  • 我只是在我的家用电脑上运行它作为一个实验,所以最大 38Mb/s - 我已经测试了几次,维基百科似乎坚持得很好......
  • 所以你打算打印出来? img.labnol.org/di/wikipedia-print.jpg
  • @mplungjan what-if.xkcd.com/59

标签: javascript function recursion


【解决方案1】:

递归调用需要是这样的:

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);

【讨论】:

  • 感谢您的帮助,我现在没有得到任何输出对象。上面你是故意使用key 来引用现有变量还是应该重命名?
  • @JakeStanger 键在 for in 循环中定义。如果还有另一个名为 key 的 var,您应该重命名其中一个...
  • 认为是这样。我仍然没有输出。让我把它上传到 Github,我会用链接编辑我的原始帖子......
  • @JakeStanger 好的。但我会离开 SO 一段时间,明天可能会有反应
  • 没关系,我不着急。这只是我业余时间的一个小实验。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2020-08-05
  • 2019-06-16
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多