2016-12-05 2 views
1

Я использую Express.js как промежуточное программное обеспечение для своего приложения. Мое приложение-интерфейс вызывает экспресс-маршрут каждые пару секунд с разными параметрами. Затем маршрут вызывает вызовы для каждого параметра на сторонний api. Внутри каждого из этих вызовов данные добавляются в массив. После цикла for я отправляю массив обратно во внешний интерфейс.Экспресс-массив отправки JS всегда пуст

Я объявляю массив внутри маршрута, но возвращаемый результат пуст. Когда я объявляю массив вне маршрута, он работает, но это не оптимально, когда одновременно выполняется несколько запросов.

server.js

app.get('/prices', function(req, res){ 

//array for holding all feeds 
var feedData = []; 

//Url params 
var target = req.param('target'); 

//Convert the params to an array 
var targetArray = target.split(','); 

//Loop through targets and do request 
for (var i = 0; i < targetArray.length; i++) { 

    //API endpoint 
    var url = xxx; 
    request(url, function (error, response, body) { 

    //Parse the XML body to javascript objects or json 
    parseString(body, function (err, result) { 


    //Store result in js object 
    var resultObject = result; 
    var arrayObject = resultObject.quotes.quote; 

    feedData.push(arrayObject[0]) 

    }); 

}); 
} 
console.log(feedData); 
res.send(feedData); 

//Clear feedData 
feedData = []; 


}); 

Так Суть заключается в том, что массив пуст. Какие-либо предложения?

+1

'async' просит – Weedoze

ответ

3

Тебя укусил асинхронной природы узла JS (хорошо, Javascript)

Вызов request является асинхронным, и принимает обратный вызов, но вы плинтуса над ним, так что ваш окончательный console.log(feedData); и т.д. ... вызывается до вызова обратного вызова request.

Посмотрите на async модуле, в частности eachSeries

Беспоставочного проверенного пример кода, используя библиотеку асинхронной:

app.get('/prices', function(req, res) { 

    //Url params 
    var target = req.param('target'); 

    //Convert the params to an array 
    var targetArray = target.split(','); 

    //array for holding all feeds 
    var feedData = []; 

    async.eachSeries(targetArray, function(targetArrayItem, cb) { 

     request(url, function(error, response, body) { 
      //Parse the XML body to javascript objects or json 
      parseString(body, function(err, result) { 


       //Store result in js object 
       var resultObject = result; 
       var arrayObject = resultObject.quotes.quote; 

       feedData.push(arrayObject[0]) 

       //call the callback to iterate next item in targetArray 
       cb(); 
      }); 
     }); 

    }, function(err) { 
     //all done 

     console.log(feedData); 
     res.send(feedData); 

     //Clear feedData 
     feedData = []; 
    }) 
}); 
+1

Спасибо. У меня было ощущение, что меня атакует асинхронный поезд, просто не мог понять. Теперь имеет смысл. – TietjeDK

+0

без проблем, рад, что это помогло – Alex

0

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

app.get('/prices', function(req, res){ 

//array for holding all feeds 
var feedData = []; 

//Url params 
var target = req.param('target'); 

//Convert the params to an array 
var targetArray = target.split(','); 

//Loop through targets and do request 
for (var i = 0; i < targetArray.length; i++) { 

    //API endpoint 
    var url = xxx; 
    request(url, function (error, response, body) { 

    //Parse the XML body to javascript objects or json 
    parseString(body, function (err, result) { 


    //Store result in js object 
    var resultObject = result; 
    var arrayObject = resultObject.quotes.quote; 

    feedData.push(arrayObject[0]); 

    //If is last request return result 
    if(i==targetArray.length-1){ 
      console.log(feedData); 
      return res.send(feedData); 
    } 
    }); 

}); 
} 
}); 
+0

Это не сработает, вы 'targetArray' вне обратного вызова для' request' - и ничего не итерации цикла for – Alex

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