js中如何将递归方法改成非递归方法

how to change recursive method into non recursive one in js

我写了一个小代码来从 GitHub 加载追随者树。

它适用于我的递归版本,但我无法获得我的 "stack-que" 版本 运行。

我在完成循环后收到了我的回复,这就是问题所在;我的递归解决方案使用相同的 loadFollowers 方法,但由于其调用结构,它会生成所需的树。

我是否应该以某种方式关闭通话中的异步功能?

function loadFollowers(user,field,callback){
  path = 'https://api.github.com/users/'+user.info[field]+'/followers';
  path += '?client_id=' + pass.client_id + '&client_secret='+pass.client_secret

  console.log("path:"+path+' field: '+field+' node: '+user);

  $.get(path,function(followers){
    for(var i = 0;i < followers.length; i++){ 
      current = new Node();
      current.info = followers[i];
      user.addFollower(current);
      callback();
    };
  });
}

function loadNetworkNonROld(node,depth,field){
var toVisit = [];
var visited =[];
var deep;
var current;
var curr;

  toVisit.push([node,depth]); // saves [node,level] to control how deep it is 
                              // starts at initial node

  while (toVisit.length > 0){   
      curr = toVisit.shift();
      current = curr[0];
      deep = curr[1];
      if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
        visited.push(current.info[field]);
        loadFollowers(current,field,function(){ 
            for(var i=0;i < current.followers.length; i++){
              toVisit.push([current.followers[i],deep-1]);
            }
        });
      }  
  }
  return visited;  
}

工作正常的递归版本如下:

function loadNetwork(node,depth,field){

  loadFollowers(node,field,function(){
  if (depth == 0){return;}
  for(var i=0; i < node.followers.length; i++){
    current = node.followers[i];
    id = current.info[field];
    if (networkAllUsers.indexOf(id)===-1)
    { 
      networkAllUsers.push(id);
      console.log(id);
      loadNetwork(current,depth-1,field);
    }  
  }});
}

github link 是:https://github.com/marcinwal/myownnode.git 代码在 public/javascript/main.js 文件中。

看起来问题很可能是迭代版本中 loadFollowers 的异步 运行ning。

然而,你的问题的关键问题在于,当你向我们展示代码时,你没有向我们展示你遇到的错误,也没有说明 'stack-que' 是什么或回复评论要求澄清。

此外,您没有向我们提供有关如何 运行 您的代码来复制您遇到的问题的说明。查看您的代码,我进行了一系列猜测,您可以在这个屏幕截图中看到一些结果:

并且我适当地缩进了您的迭代代码,并添加了一些日志记录以生成上述输出的一部分:

function loadNetworkNonROld(node,depth,field){
  var toVisit = [];
  var visited =[];
  var deep;
  var current;
  var curr;

  toVisit.push([node,depth]); // saves [node,level] to control how deep it is 
                              // starts at initial node

  while (toVisit.length > 0){  
      console.log(toVisit) 
      curr = toVisit.shift();
      current = curr[0];
      deep = curr[1];
      if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
        visited.push(current.info[field]);
        console.log(visited) 
        loadFollowers(current,field,function(){ 
          for(var i=0;i < current.followers.length; i++){
            toVisit.push([current.followers[i],deep-1]);
            console.log('loadFollowers:' + toVisit) 
          }
        });
      }  
  }
  return visited;  
}

现在我可以花更多的精力来研究你的代码,猜测我们是否得到了一些输出,你有什么,但你并没有让人们很容易提供帮助。

从我在控制台日志中看到的情况来看,在我看来,您正在将所有节点推到深度 1,而它们永远不会达到深度 0,因此它只是 运行 永远持续不断。而在递归版本中,深度变为 0。

我修改了你的代码:

  while (toVisit.length > 0){  
      console.log(toVisit) 
      curr = toVisit.shift();
      current = curr[0];
      deep = curr[1];
      if((visited.indexOf(current.info[field])===-1) && (deep > 0)){
        visited.push(current.info[field]);
        console.log('loadNetworkNonROld: '+deep);
        loadFollowers(current,field,deep,function(depth){ 
          console.log('loadFollowers:' + (depth-1));
          for(var i=0;i < current.followers.length; i++){
            toVisit.push([current.followers[i],(depth-1)]);
          }
        });
      }  
  }
  console.log('loadNetworkNonROld: visited:'+JSON.stringify(visited));
  return visited;  
}

对 loadFollowers 函数进行并行更改,以便实际传递深度值。现在代码 运行s 没有永远迭代,但是 javascript 的异步性质意味着结果在任何网络调用完成之前返回 - 因此访问的结果只是第一个用户。