2016-01-21 8 views
0

У меня есть array данных, против которых я запрашиваю api с использованием request. С помощью команды callback после каждого ответа на запрос, который был сделан. Однако при этом я запускаю параллельные запросы для всех элементов массива. Вот что я делаю:запрос api in foreach

exports.getData = function(arr, cb){ 
    arr.forEach(function(data){ 
     var query = { 
      //some data here 
     }; 
     request({ 
      url: 'http://x/y', 
      json: query, 
      method: 'POST', 
      headers: { 
       'Content-Type': 'application/json' 
      } 
     }, function(error, res, body){ 
      if (error){ 
       console.log(error); 
      } else{ 
       cb(res.body); 
      } 
     }); 
    }); 
}; 

Я хочу setTimeOut из x seconds в приведенном выше коде. Должен ли я выполнять наивную задержку после каждого запроса? Или что-то другое?

+0

, так что вы хотите сделать запрос синхронным? – Sachin

+1

Используйте обещания начать обратный вызов после завершения всех запросов – dave

+0

Есть ли проблема с асинхронностью запросов? Обычно это будет намного лучше для производительности приложения, так что вы не блокируете каждую итерацию цикла, ожидая выполнения предыдущего запроса. –

ответ

1

Обновлено: параллельный запрос к серии запросов.

Вы должны использовать серию запросов. используйте async модуль. см. ниже

exports.getData = function(arr, cb){ 

    // make an array of function 
    var funcArray = []; 

    arr.forEach(function(data){ 
     var query = { 
      //some data here 
     }; 

    funcArray.push(function(callback){  
     request({ 
      url: 'http://x/y', 
      json: query, 
      method: 'POST', 
      headers: { 
       'Content-Type': 'application/json' 
      } 
     }, function(error, res, body){ 
      // 5 second interval for each request 
      setTimeout(function(){ callback(error, body); }, 5000); 
     }); 
     }); 
    }); 


    // now run all tasks on series 
    async.series(funcArray,function(err, result){ 

     // now you will get result for all request 

     // handle error 
     // do what ever you want with result 
    }); 
} 
+0

Как добавить «тайм-аут» между каждым запросом? – faizanjehangir

+0

, тогда вы должны использовать 'async.series'. теперь задерживайте перед выполнением обратного вызова. , потому что следующий запрос будет выполнен, когда вы вызываете функцию обратного вызова. 'setTimeout (функция() {обратный вызов (ошибка, тело);}, 1000);' –

+0

Я обновил ответ –

0

forEach loop идеально подходит для короткого замыкания, поэтому вы можете сначала добавить все параметры запроса в queryPool, а затем выполнить их по одному.

Вы можете обратиться к этому коду.

exports.getData = function(arr, cb){ 
 
    var queryPool = []; 
 
    function execQuery(){ 
 
     if(queryPool.length == 0) return 
 
     var query = queryPool.slice(0,1) 
 
     queryPool = queryPool.slice(1,queryPool.length) 
 
     request({ 
 
      url: 'http://x/y', 
 
      json: query, 
 
      method: 'POST', 
 
      headers: { 
 
       'Content-Type': 'application/json' 
 
      } 
 
     }, function(error, res, body){ 
 
      if (error){ 
 
       console.log(error); 
 
      } else{ 
 
       cb(res.body); 
 
      } 
 
      execQuery(); 
 
     }); 
 
    } 
 
    arr.forEach(function(data){ 
 
     var query = { 
 
      //some data here 
 
     }; 
 
     queryPool.push(query); 
 
    }); 
 
    execQuery(); 
 
};

Этот код принимает функция, заданная в запросе выполняется в любых условиях, успеха или неудачи.