2015-02-23 97 views
0

我編寫了一個小代碼來加載GitHub中的追隨者樹。如何將遞歸方法更改爲js中的非遞歸方法

它對我的遞歸版本運行良好,但我無法讓我的「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的鏈接是:https://github.com/marcinwal/myownnode.git 和代碼公共/ JavaScript的/ main.js文件。

+1

問題代碼在哪裏?你顯示函數'loadNetworkNonROld()',但它永遠不會被使用。還提到'stack-que',但是那是什麼?總體問題並不清楚。這是不是一個好主意,用'異步:FALSE' – charlietfl 2015-02-23 16:21:51

+0

它在使用$( '#formdepth')上( '提交',函數(事件){ event.preventDefault(); 深度= $(」。 #深度')。VAL(); // loadNetwork(user,depth,'login'); networkAllUsers = loadNetworkNonROld(user,depth,'login') }); – marcinwal 2015-02-23 18:53:47

+1

你能否告訴你爲什麼你想使用非遞歸函數,當你已經有一個遞歸的函數時,你會想要什麼? – Tomalak 2015-02-25 09:33:49

回答

0

看起來好像這個問題很可能是迭代版本中loadFollowers的異步運行。

但是你的問題的關鍵問題是,當你向我們展示的代碼,你不告訴我們您所遇到的錯誤,你不說什麼「堆棧闕」是或迴應評論請求爲了澄清。

此外,您不會告訴我們如何運行代碼來複制遇到的問題。查看你的代碼中,我採取了一系列猜測,你可以看到一些結果在這個屏幕截圖:

screen shot of trying to replicate the error

,我來適當地縮進您的迭代的代碼,並添加了一些記錄產生的上述部分輸出:

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,所以它只是運行上和永遠。平行更改loadFollowers功能

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

這樣的深度值實際上是沿着通過:而在遞歸版本的深度到達0

我修改您的代碼如下所示。現在代碼運行沒有永遠的迭代,但JavaScript的異步性質意味着之前的任何完成了網絡調用的返回結果 - 因此訪問結果只有有史以來第一個用戶。

+0

歡迎您 - 如果答案正確,請點擊正確 – 2015-06-15 17:17:14