2015-02-23 3 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', но что это? Общий вопрос не совсем понятен. Не всегда полезно использовать 'async: false' – charlietfl

+0

, он используется в $ ('# formdepth'). On ('submit', function (event) { event.preventDefault(); depth = $ (' #depth ').Val(); // loadNetwork (пользователь, глубина, 'login'); networkAllUsers = loadNetworkNonROld (пользователь, глубина, 'login') }); – marcinwal

+1

Можете ли вы объяснить, почему вы хотите использовать нерекурсивную функцию, когда у вас уже есть рекурсивный, который делает то, что вам нужно? – Tomalak

ответ

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, поэтому он просто работает постоянно и постоянно. В то время как в рекурсивной версии глубина доходит до 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 поэтому значение глубины фактически передается вместе. Теперь код работает без повторения навсегда, но асинхронный характер javascript означает, что результат возвращается до завершения любого из сетевых вызовов - следовательно, результат посещения - это только первый пользователь.

+0

приветствуются - пожалуйста, нажмите, как можно правильно, если это правильный ответ –

Смежные вопросы