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

В идеале я хотел бы отправить массив результатов каждого запроса обратно вызывающей стороне.

const request = require('request');

module.exports = {

apiRatingCall: function (input, callback) {

var output = []

  for (var i = 0; i < input.length; i++) {
  var options = {
    url: 'someAPIURL' + '?longitude=' + input[i].longitude + '&latitude=' + input[i].latitude + '&name=' + input[i].name,
    headers: {
      'x-api-version': 2
    }
  };

  request(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {

      var info = JSON.parse(body)
      output.push(info) // this is not working as ouput is undefined at this point
    }
  })
  }
  callback(output)
  }
}

Спасибо

1
alex99_14 7 Янв 2017 в 09:38

3 ответа

Лучший ответ

Мой ответ, возможно, не очень нормативный в программировании, это единственный способ для этой проблемы, я обещаю

module.exports = {

apiRatingCall: function (input, callback) {

var output = []

for (var i = 0; i < input.length; i++) {
var options = {
  url: 'someAPIURL' + '?longitude=' + input[i].longitude + '&latitude=' +    input[i].latitude + '&name=' + input[i].name,
 headers: {
  'x-api-version': 2
 }
};

 request(options, function (error, response, body) {
   if (!error && response.statusCode == 200) {

    var info = JSON.parse(body)
    output.push(info) // this is not working as ouput is undefined at this    point
   }
 })
 }
 setTimeout(function(){
   callback(output)
 },500)

 }
}
0
farhadamjady 7 Янв 2017 в 19:50

Посмотрите на асинхронный модуль. Это хороший модуль для асинхронной работы с массивом и коллекцией, если вы не хотите использовать bluebird и обещания.

У npm установить async -S.

const request = require('request');
const async = require('async);

module.exports = {

  apiRatingCall: function (inputs, callback) {

  var output = []


  async.each(inputs, function(input, cb) {
      var options = {
      url: 'someAPIURL' + '?longitude=' + input.longitude + '&latitude=' + input.latitude + '&name=' + input.name,
      headers: {
       'x-api-version': 2
      }
      request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {

          var info = JSON.parse(body)
          output.push(info); 
          cb();
        }else{
          //if any of the request fails then return error
          cb(error);
        }
    })

    }, function(err){
      if(!err){
         return callback(output);
      }else{
        //if any of the request return error
        return callback(err);
      }
   });
}
0
Mustafa Mamun 7 Янв 2017 в 20:20

Вы можете проверить конец цикла for и выполнить свой callback

var loopCallback = function(error, response, body) {
  if (!error && response.statusCode == 200) {
     var info = JSON.parse(body)
     output.push(info)
  }
  if( i == input.length - 1){ //checking index for completion of loop
    callback(output);
  }
}

request(options, loopCallback})
0
Jyothi Babu Araja 7 Янв 2017 в 07:09