2015-07-02 3 views
0

Прежде всего, я не испытываю асинхронного программирования, так что извините, если я пропустил что-то очевидное.Проблема с попыткой запуска синхронных запросов REST в узле

Я вижу этот вопрос много. Я знаю, что людям не нравится форсировать синхронность в Javascript, но это необходимо в этом случае. Я делаю громкие звонки в производственную базу данных, которая не может занять слишком много нагрузки из-за того, как часто она используется. Из-за этого я настраиваю свой код в цикле, чтобы сделать запрос, дождаться подтверждения, что он закончен, спать в течение 2 секунд и затем сделать следующий запрос. Это связано с тем, что я собираюсь получать много данных с этого сервера еженедельно в течение примерно 10-20 минут.

Вот код, который у меня есть. Сон - это функция, которая заставляет программу ждать с использованием класса Date.

var thread = function(cb){ 
     cb(); 

    }; 


    do{ 

     var x = thread(function(){ 
      request.post(options, function(e, r, body){ 
       console.log(e); 
       console.log(r.statusCode); 
       issues.push(body["issues"]); 
       maxResults = body["total"]; 
       options.body.startAt += 25; 
       console.log("Going to sleep"); 

      }); 
      sleep(2000); 
     }); 
     console.log("Waking up and moving to the next cycle"); 

    }while(issues.length < maxResults); 
    console.log("Finished with the requests"); 
} 

хотя у меня есть функция обратного вызова, мой код по-прежнему запускает запросы асинхронно. Поскольку я оставляю maxResults null, очевидно, что мой обратный вызов не работает. Это мой вывод:

Waking up and moving to the next cycle 
Finished with the requests 
Going to sleep 
+1

Вы не можете сделать это. Вместо этого вы должны использовать обещания. – SLaks

+0

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

+0

http://blog.slaks.net/2015-06-10/advanced-promise-usage/#sequential-operations – SLaks

ответ

1

Вам необходимо сделать рекурсивную асинхронную функцию.

Это будет выглядеть примерно так:

function fetch(existingIssues) { 
    return sendRequest().then(function() { 
     existingIssues.push(...); 
     if (existingIssues.length >= maxResults) 
      return existingIssues; 
     else 
      return fetch(existingIssues); 
    }); 
} 
fetch([]).then(...); 
+0

Это кажется очень опасным. Я работаю с большими объектами, строками таблицы с ~ 30 столбцами, включая описание и итоговые столбцы. Это должно быть в состоянии обрабатывать ~ 5-10 ГБ данных в целом, поэтому рекурсивная функция быстро станет раздутой и медленной. Я имею в виду, если это единственный способ, это единственный способ ... но нет ли другого решения? –

+0

@ user3723527: Нет. Асинхронная рекурсия не раздувает стек вызовов; каждая асинхронная граница начинается с пустого стека вызовов. В этом нет ничего плохого. – SLaks

+0

Я возьму ваше слово за это, но мне интересно, как это работает. Если у меня есть асинхронная функция var foo = function() {var x = 2; return x + foo();} не будет ли заполнять стек бесконечными переменными, установленными на 2? Как Javascript избегает этого? Является ли он достаточно умен, чтобы дифференцировать и мусор собирать функции, которые выпадают после рекурсивного вызова или не использовать скользящие переменные в возвращаемом значении? –

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