2017-02-05 3 views
1

У меня есть рекурсивная функция 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; 
} 

Любая помощь приветствуется, заранее.

** EDIT: ** Ссылка: https://github.com/JakeStanger/Wikipedia-Mapper/blob/master/init.js#L53

+0

Это очень реальная возможность сосать wikipedia на ваш сервер. Вы уверены, что хотите сделать это на своем сервере и разрешили это делать Wikipedia? – mplungjan

+1

Заменить 'Promise.all()', 'Array.prototype.map()' для 'for..in' циклов. См. Также [многократное, последовательное получение() Promise] (http://stackoverflow.com/questions/38034574/multiple-sequential-fetch-promise) – guest271314

+0

Я только запускаю его на своем домашнем компьютере в качестве небольшого эксперимента, поэтому макс. 38 Мбит/с - я тестировал его несколько раз, и Википедия, похоже, отлично держит ... –

ответ

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

Спасибо за помощь, однако я не получаю никакого выделенного объекта. Вы уже использовали «ключ» для обозначения существующей переменной или ее следует переименовать? –

+0

@ Кнопка JakeStanger определена в цикле for for. если theres другой var называется ключ, вы должны переименовать один из них ... –

+0

Поняв, что это так. Я все еще не получаю выход. Lemme загрузите его в Github, и я отредактирую свой оригинальный пост со ссылкой ... –

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