I wrote code to get data from HTTP service and save it in MongoDB.
Now I test it directly from the console node script.js
The script does its job, but it doesn't exit. I have to do CTRL+C to stop it
Why does it not exit automatically? What place in the code is best for process.exit(0) (if it is needed)?
/*global Promise, getData, httpReq, searchData, getHotData, storeData*/
var http = require('http');
var CoubVideo = require('./models/coubdb.js');
function CoubApi (url, numPerPage, numOfPages) {
this.url = url;
this.numOfPages = numOfPages;
this.numPerPage = numPerPage;
this.getData = getData;
this.httpReq = httpReq;
this.searchData = searchData;
this.getHotData = getHotData;
this.storeData = storeData;
}
// Get data from server
function httpReq (url) {
var promise = new Promise (function (resolve, reject) {
http.get(url, function (res) {
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
if(data.length > 0) {
resolve(JSON.parse(data));
} else {
reject("Error: HTTP request rejected!");
}
});
}).on('error', function (err) {
console.log(err);
});
});
return promise;
}
// Store data in MongoDB
function storeData (data, per_page) {
function insertVideoDoc (i) {
CoubVideo.count({id: data.coubs[i].id}, function (err, count) {
if (err) {
console.log(err);
}
if (count === 0 || count === null) {
var video = new CoubVideo(data.coubs[i]);
video.save(function (err) {
if (err) {
console.log(err);
}
console.log("Saved successfully!");
});
} else {
console.log("Duplicate");
}
});
}
var i;
for(i = 0; i < per_page; i++) {
insertVideoDoc(i);
}
}
// Search for coubs
function searchData (searchtext, order, page, per_page) {
var url = this.url +
"search?q=" + searchtext +
"&order_by=" + order +
"&per_page=" + per_page +
"&page=" + page;
this.httpReq(url).then(function (data) {
this.storeData(data, per_page);
}.bind(this));
}
// Get hot coubs
function getHotData (order, page, per_page) {
var url = this.url +
"timeline/hot?page=" + page +
"&per_page=" + per_page +
"&order_by=" + order;
this.httpReq(url).then(function (data) {
this.storeData(data, per_page);
}.bind(this));
}
// Get data
function getData () {
var i;
for(i = 0; i < this.numOfPages; i++) {
this.getHotData("newest_popular", i, this.numPerPage);
}
}
var coub = new CoubApi("http://coub.com/api/v2/", 2, 50);
coub.getData();
Related
This is the async function:
async function getpackages(conn, childId, callback) {
var childId = childId;
var request6 = new sql.Request(conn);
var packageQuery = "select OrderId,ChildID from dbo.tbl_Scheduler where NoOfMealsLeft>0 and ChildId=" + childId;
await request6.query(packageQuery, function (err, packagelist) {
if (!err && packagelist.recordsets.length > 0) {
console.log("Error:" + err + "Result:" + util.inspect(packagelist.recordsets[0]));
var orderdetail_ = [];
for (i = 0; i < packagelist.recordsets[0].length; i++) {
orderdetail_.push(packagelist.recordsets[0][i].OrderId);
}
console.log("-->" + orderdetail_);
callback(null, packagelist.recordsets[0]);
} else if (packagelist.recordsets.length < 1) {
callback("Not a valid id input", null);
}
});
};
I need to call the orderdetails_ array in the query. The array contains four data and I need to iterate over 4 data one by one, using the or in the SQL query.
module.exports.newscheduledmeal = function (req, res, next, callback) {
let entered_date = req.query.date;
let childId = req.query.id;
let current_date = new Date().toISOString().slice(0, 10);
if (entered_date < current_date) {
return callback('Please enter date more than or equal to current date.', null);
} else
var conn = new sql.ConnectionPool(dbConfig);
try {
conn.connect().then(function () {
var request = new sql.Request(conn);
getpackages(conn, childId, function (err, orderid) {
if (err) {
callback(err, null);
} else
var PackageidQuery = "select PackageId from dbo.tbl_Order where OrderId=";
request.query(PackageidQuery, function (err, packagelist) {
if (!err) {
conn.close();
callback(null, packagelist.recordsets);
} else {
conn.close();
callback("Error", null);
}
});
});
});
} catch (err) {
console.log("Exception occured:" + err);
conn.close();
callback(err, null);
}
};
I want to get the details of the array which is in getpackages to be used in the module section and specifically in the SQL query section.
I get the error that function is not found.
I don't get it.. is it because of the callback in the https.get?
I want to call the callback function when the http request is done.
const happy = ['happy'];
twitterService.twitter(happy, '1233,1233', '50', function (length) {
console.log(length + " bepedie boopdap");
});
twitter.js
module.exports.twitter = function (hashtags, location, distance, callbackLength) {
if (hashtags.length !== 0) {
let hashURL = createHashtagUrl(hashtags);
const options = {
host: config.apiURL,
path: '/1.1/search/tweets.json?q=' + hashURL + '&geocode=' + location + ',' + distance + 'km&count=100',
method: 'GET',
headers: {
'Authorization': 'Bearer ' + config.base64Token
}
};
https.get(options, function (res) {
let body = '';
res.on('data', function (data) {
body += data;
});
res.on('end', function () {
let jsonObj = JSON.parse(body);
let length = jsonObj.statuses.length;
callbackLength(length); // HERE its says .. is not a function
})
.on('error', function (e) {
console.log("ERROR BEEP BEEP" + e);
});
});
}
};
function createHashtagUrl(hashtags) {
let hashURL = config.hashtagUnicode + hashtags[0];
for (let i = 1; i < hashtags.length; i++)
hashURL += '+OR+' + config.hashtagUnicode + hashtags[i];
return hashURL;
}
anyone an idea?
Not sure, but maybe need to change request part.
var req = https.get(options, function (res) {
let body = '';
res.on('data', function (data) {
body += data;
});
});
req.on('end', function () {
let jsonObj = JSON.parse(body);
let length = jsonObj.statuses.length;
callbackLength(length);
})
.on('error', function (e) {
console.log("ERROR BEEP BEEP" + e);
});`enter code here`
I have the following code inside a webworker,
onmessage = function(e)
{
var data;
var message = e.data;
sendTimeSeries = false;
var semicolon = message.split(";");
for (var i=0; i<semicolon.length;i++)
{
var colon= semicolon[i].split(":");
for(var j=0; j<colon.length; j++)
{
if(colon[j] == "Insert TimeSeries")
{
stringTimeSeriesTableData = ""
data = colon[j+1].split(" ");
prevLetter = data[0];
getAllRecords(prevLetter).then(addTimeSeries).then(getAllTimeSeries).then(sendMessage); //use of promises
}
}
}
}
The methods getAllRecords, addTimeSeries and getAllTimeSeries are being called in the correct order (won't go into the next method until the previous one has finished executing. However, the sendMessage webworker method is being called before finishing the getAllTimeSeries method.
getAllRecords():
function getAllRecords(letter)
{
var deferred = $.Deferred();
var trans = db.transaction(["ObservableStates"],"readonly").objectStore("ObservableStates").index('letterIndex');
var request = trans.openCursor(IDBKeyRange.only(letter));
request.onsuccess = function(event)
{
cursor = event.target.result;
if(cursor)
{
count = count + 1;
console.log(cursor.value);
addRecordToHistory(cursor.value);
deleteObservableStates(cursor.primaryKey);
while(cursor.continue())
{
}
}
if(cursor==null)
{
console.log('ready from count');
deferred.resolve();
}
}
request.onerror = function(event)
{
console.log('ERROR LOADING DATA FROM TABLE');
}
return deferred.promise();
}
addTimeSeries
function addTimeSeries()
{
var deferred = $.Deferred();
timeSeries = {
l:prevLetter, t:count
}
request = db.transaction(['TimeSeries'], "readwrite").objectStore('TimeSeries').add(timeSeries);
request.onerror = function(event)
{
console.log("Unable to add timeSeries to table TimeSeries");
}
request.onsuccess = function(event)
{
console.log("TimeSeries State Added");
deferred.resolve();
}
return deferred.promise();
}
getAllTimeSeries()
function getAllTimeSeries()
{
var deferred = $.Deferred();
req = db.transaction(['TimeSeries'], "readonly").objectStore('TimeSeries').openCursor();
req.onerror = function(event)
{
console.log("Unable to stringify all records");
}
req.onsuccess = function(event)
{
cursor=event.target.result;
if(cursor)
{
stringTimeSeriesTableData += cursor.value.l + "," + cursor.value.t + ";";
while(cursor.continue())
{
}
}
if(cursor==null)
{
console.log(stringTimeSeriesTableData);
sendTimeSeries = true;
deferred.resolve();
console.log('got all time series');
}
}
return deferred.promise();
}
Is there something I'm missing here? Thanks
What I am trying to do is run functions that will send out messages. The problem with node js is that it does not return in sequence. I do however want each function to run in the sequence that it is coded.
Not really sure what I'm missing here.
Right now I can get it to return only message 1 and message 2 in sequence BUT I want to go all the way from callfirstmessage to callfifthmessage. When I have tried to do this they all get returned out of order.
var promise = new Promises(function(resolve, reject) {
// do some async stuff
callfirstmessage();
//resolve(data);
if (success) {
resolve(data);
} else {
reject(reason);
}
});
promise.then(function(data) {
// function called when first promise returned
return new Promises(function(resolve, reject) {
// second async stuff
callthirdmessage();
//resolve(data);
if (success) {
resolve(data);
} else {
reject(reason);
}
});
}, function(reason) {
// error handler
}).then(function(data) {
callsecondmessage();
}, function(reason) {
// second error handler
});
I have looked at a few different posts talking about this topic and I have used those suggestions. I think my issue here is not being able to successfully chain these together. I have spent a few days on this with no additional progress...I need help bad!
-----------------------edit----------------------------
I think I need to apply something similar to this .then I have found here: https://coderwall.com/p/ijy61g/promise-chains-with-node-js. But for some reason it is still sending messages at random.
Maybe, I'm just going in the completely wrong direction. :/
Below is everything I am working with
// dependencies
console.log("starting program");
var async = require('async');
var AWS = require('aws-sdk');
var Converter = require("csvtojson").Converter;
var util = require('util');
var Promises = require('pinkie-promise');
var vow = require('vow');
var s3 = new AWS.S3();
var snsTopicEMAIL = new AWS.SNS({
params: {
TopicArn: 'arn:aws:sns:xxxxxxxxxxxxxxxxxxxxxxxx'
}
});
var snsTopicSMS = new AWS.SNS({
params: {
TopicArn: 'arn:aws:sns:xxxxxxxxxxxxxxxxxxxxxxxxx'
}
});
var abort = false;
//SMS
function topDSRsms(csvJSON) {
var ytdTopReg = "";
if (csvJSON.length < 1) {
console.error("Not enough data records in CSV to compose an SMS. Aborting. count:" + csvJSON.length);
tdTopReg = "There was an error. Please contact IT for assistance.";
abort = true;
throw '';
}
ytdTopReg = "";
for (var i = 0; i < csvJSON.length; i++) {
var csvItem = csvJSON;
if (csvItem[i].KPIvalue.length > 0 && csvItem[i].KPI.length > 0) {
var KPI = " " + csvItem[i].KPI + ":" + csvItem[i].KPIvalue + "\n";
} else {
KPI = " ";
}
if (csvItem[i].TrendValue1.length > 0 && csvItem[i].Trend1.length > 0) {
var trend1 = "\n" + svItem[i].Trend1 + ":" + csvItem[i].csvItem[i].TrendValue1;
} else {
trend1 = "";
}
if (csvItem[i].TrendValue2.length > 0 && csvItem[i].Trend2.length > 0) {
var trend2 = "\n" + csvItem[i].Trend2 + ":" + csvItem[i].TrendValue2;
} else {
trend2 = "";
}
if (csvItem[i].TrendValue3.length > 0 && csvItem[i].Trend3.length > 0) {
var trend3 = "\n" + csvItem[i].Trend3 + ":" + csvItem[i].TrendValue3;
} else {
trend3 = "";
}
ytdTopReg += "\n#" + (i + 1) + KPI + csvItem[i].RankTrend + ":" + csvItem[i].RankTrendValue + trend1 + trend2 + trend3;
}
return ytdTopReg;
}
function dshSmsStr(csvJSON) {
return "DSR:" +
topDSRsms(csvJSON);
}
//email
function topDSREmail(csvJSON) {
var ytdTopReg = "";
ytdTopReg = "Top orders By Region - ";
for (var i = 0; i < csvJSON.length; i++) {
if (csvJSON.length < 1) {
console.error("Not enough data records in CSV to compose an email. Aborting.");
ytdTopReg = "There was an error. Please contact IT for assistance."
abort = true;
throw '';
//return -1;
} else {
var csvItem = csvJSON;
if (csvItem[i].KPIvalue.length > 0 && csvItem[i].KPI.length > 0) {
var KPI = " " + csvItem[i].KPI + ":" + csvItem[i].KPIvalue + "\n";
} else {
KPI = "";
}
if (csvItem[i].TrendValue1.length > 0 && csvItem[i].Trend1.length > 0) {
var trend1 = "\n" + svItem[i].Trend1 + ":" + csvItem[i].csvItem[i].TrendValue1;
} else {
trend1 = "";
}
if (csvItem[i].TrendValue2.length > 0 && csvItem[i].Trend2.length > 0) {
var trend2 = "\n" + csvItem[i].Trend2 + ":" + csvItem[i].TrendValue2;
} else {
trend2 = "";
}
if (csvItem[i].TrendValue3.length > 0 && csvItem[i].Trend3.length > 0) {
var trend3 = "\n" + csvItem[i].Trend3 + ":" + csvItem[i].TrendValue3;
} else {
trend3 = "";
}
ytdTopReg += "\n#" + (i + 1) + KPI + csvItem[i].RankTrend + ":" + csvItem[i].RankTrendValue + trend1 + trend2 + trend3 + "\n";
}
}
return ytdTopReg;
}
function dshEmailStr(csvJSON) {
return "DSR:" +
topDSREmail(csvJSON);
}
console.log("compiled totals string and customer string");
exports.handler = function(event, context) {
// Read options from the event.
console.log("Reading options from event:\n", util.inspect(event, {
depth: 5
}));
var srcBucket = event.Records[0].s3.bucket.name;
console.log("got src bucket name");
// Object key may have spaces or unicode non-ASCII characters.
var srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
console.log("src key decoded");
// Download the CSV file from S3, Extract&Load data into DynamoDB, and notify end users.
async.waterfall([
function downloadCSV(next) {
// Download the Daily Sales Highlights CSV file from S3 into a buffer.
s3.getObject({
Bucket: srcBucket,
Key: srcKey
},
next);
},
function parseCSV(response, next) {
console.log(response.ContentType);
var csvStream = AWS.util.buffer.toStream(response.Body);
var csvJSON = [];
var converter = new Converter({});
//end_parsed will be emitted once parsing finished
converter.on("end_parsed", function(jsonArray) {
console.log(jsonArray); //here is your result jsonarray
csvJSON = jsonArray;
next(null, csvJSON);
});
//read CSV from stream
csvStream.pipe(converter);
},
function updateState(csvJSON, next) {
//Update state in DynamoDB
next(null, csvJSON);
},
function notifyEndUsers(csvJSON, next) {
//Notify end users
console.log("\n\nNotifying SMS end users...\n\n");
console.log(dshSmsStr(csvJSON));
console.log("\n\nNotifying email end users...\n\n");
console.log(dshEmailStr(csvJSON));
//email
snsTopicEMAIL.publish({
Message: dshEmailStr(csvJSON)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
//SMS
var datastr = dshSmsStr(csvJSON);
var strlen = dshSmsStr(csvJSON).length;
var ranscript = false;
var completemsg1 = false;
var completemsg2 = false;
var completemsg3 = false;
var completemsg4 = false;
var completemsg5 = false;
var completemsg6 = false;
function callfirstmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(0, 150)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callsecondmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(150, 300)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callthirdmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(300, 450)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callfourthmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(450, 600)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function callfifthmessage() {
snsTopicSMS.publish({
Message: dshSmsStr(csvJSON).substring(600, 750)
}, function(err, data) {
if (err) {
console.log(err.stack);
next(err);
}
console.log(data);
next(null);
});
return true;
}
function one() {
new Promises(function(resolve1, reject) {
completemsg1 = callfirstmessage();
if (completemsg1 === true) {
resolve1(true);
console.log('first success');
} else {
reject(false);
console.log('first fail');
}
});
}
function two() {
new Promises(function(resolve2, reject) {
completemsg2 = callsecondmessage();
if (completemsg2 === true) {
resolve2(completemsg2);
console.log('second success');
} else {
reject(false);
console.log('second fail');
}
});
}
function three() {
new Promises(function(resolve3, reject) {
completemsg3 = callthirdmessage();
if (completemsg3 === true) {
resolve3(completemsg3);
console.log('third success');
} else {
reject(false);
console.log('third fail');
}
});
}
function four() {
new Promises(function(resolve4, reject) {
completemsg4 = callfourthmessage();
if (completemsg4 === true) {
resolve4(completemsg4);
console.log('fourth success');
} else {
reject(false);
console.log('fourth fail');
}
});
}
function five() {
new Promises(function(resolve5, reject) {
completemsg5 = callfifthmessage();
if (completemsg5 === true) {
resolve5(completemsg5);
console.log('fifth success');
} else {
reject(false);
console.log('fifth fail');
}
});
}
console.log("\n\n Begin SMS script. Data length :" + strlen + "...\n\n");
if (strlen < 150) { //one message sent
//Will complete later
ranscript = true;
} else if (strlen < 300) { //two messages sent
//Will complete later
ranscript = true;
} else if (strlen < 450) { //three messages sent
//Will complete later
ranscript = true;
} else if (strlen < 600) { //four messages sent
one().then(function() {
return two();
})
.then(function() {
return three();
})
.then(function() {
return four();
})
.then(function() {
return five();
});
ranscript = true;
} else if (strlen < 750) { //five messages sent
//Will complete later
ranscript = true;
} else {
console.log("\n\n The SMS mesages is too large to send to end users...\n\n");
}
if (ranscript === false) {
console.log("\n\n SMS script did not run \n\n");
} else if (ranscript === true) {
console.log("\n\n SMS script successfully ran \n\n");
}
}
], function(err) {
if (err) {
console.error(
'Unable to process due to an error: ' + err
);
} else {
console.log(
'Successfully processed'
);
}
context.done();
});
}
The executor for the first promise (reformatted):
var promise = new Promise(function(resolve, reject)
{ // do some async stuff
callfirstmessage();
if (success)
{ resolve(data);
} else
{ reject(reason);
}
});
doesn't resolve or reject the returned promise asynchronously. You will need to get a call back from the asynchronous operation before resolving/rejecting the returned promise. In pseudo code something more like:
var promise = new Promise(function(resolve, reject)
{ // do some async stuff
callfirstmessage( successCallBack, failCallBack);
function successCallBack( data)
{ resolve(data);
}
function failCallBack( reason)
{ reject(reason);
}
});
In reality you may have to use a call back the asynchronous operation supports, and then analyze success or failure of the operation depending on a status property located in a request or response object.
I have a nodejs program that requests a series of XML files, parses them and then puts the output in an array which is written to disk as a CSV file.
The program mostly works, however occasionally the files end up in the wrong order in the array.
I want the order of the results to be in the same as the order as the URLs. The URLs are stored in an array, so when I get the XML file I check what the index of the URL was in the source array and insert the results at the same index in the destination URL.
can anyone see the flaw that is allowing the results to end up in the wrong order?
addResult = function (url, value, timestamp) {
data[config.sources.indexOf(url)] = {
value : value,
timestamp : timestamp,
url : url
};
numResults++;
if (numResults === config.sources.length) { //once all results are in build the output file
createOutputData();
}
}
fs.readFile("config.json", function (fileError, data) {
var eachSource, processResponse = function (responseError, response, body) {
if (responseError) {
console.log(responseError);
} else {
parseXML(body, {
explicitArray : false
}, function (xmlError, result) {
if (xmlError) {
console.log(xmlError);
}
addResult(response.request.uri.href, result.Hilltop.Measurement.Data.E.I1, moment(result.Hilltop.Measurement.Data.E.T));
});
}
};
if (fileError) {
console.log(fileError);
} else {
config = JSON.parse(data); //read in config file
for (eachSource = 0; eachSource < config.sources.length; eachSource++) {
config.sources[eachSource] = config.sources[eachSource].replace(/ /g, "%20"); //replace all %20 with " "
request(config.sources[eachSource], processResponse); //request each source
}
}
});
var writeOutputData, createOutputData, numResults = 0, data = [], eachDataPoint, multipliedFlow = 0;
writeOutputData = function (output, attempts) {
csv.writeToPath(config.outputFile, [ output ], {
headers : false
}).on("finish", function () {
console.log("successfully wrote data to: ", config.outputFile);
}).on("error", function (err) { //on write error
console.log(err);
if (attempts < 2) { //if there has been less than 3 attempts try writing again after 500ms
setTimeout(function () {
writeOutputData(output, attempts + 1);
}, 500);
}
});
};
createOutputData = function () {
var csvTimestamp, output = [];
if (config.hasOwnProperty("timestampFromSource")) {
csvTimestamp = data.filter(function (a) {
return a.url === config.sources[config.timestampFromSource];
})[0].timestamp.format("HHmm");
console.log("timestamp from source [" + config.timestampFromSource + "]:", csvTimestamp);
} else {
csvTimestamp = data.sort(function (a, b) { //sort results from oldest to newest
return a.timestamp.unix() - b.timestamp.unix();
});
csvTimestamp = csvTimestamp[0].timestamp.format("HHmm");//use the oldest date for the timestamp
console.log("timestamp from oldest source:", csvTimestamp);
}
//build array to represent data to be written
output.push(config.plDestVar); //pl var head address first
output.push(config.sources.length + 1); //number if vars to import
output.push(csvTimestamp); //the date of the data
for (eachDataPoint = 0; eachDataPoint < data.length; eachDataPoint++) { //add each data point
if (config.flowMultiplier) {
multipliedFlow = Math.round(data[eachDataPoint].value * config.flowMultiplier); //round to 1dp and remove decimal by *10
} else {
multipliedFlow = Math.round(data[eachDataPoint].value * 10); //round to 1dp and remove decimal by *10
}
if (multipliedFlow > 32766) {
multipliedFlow = 32766;
} else if (multipliedFlow < 0) {
multipliedFlow = 0;
}
output.push(multipliedFlow);
}
console.log(output);
writeOutputData(output, 0); //write the results, 0 is signalling first attempt
};
I think that the url to index code needs debugging.
Here is an example that uses an object that is pre-populated with keys in the for loop.
`
var http = require('http');
var fs = require("fs");
var allRequestsComplete = function(results){
console.log("All Requests Complete");
console.log(results);
};
fs.readFile("urls.json", function (fileError, data) {
var responseCount = 0;
if (fileError) {
console.log(fileError);
} else {
var allResponses = {};
config = JSON.parse(data); //read in config file
var requestComplete = function(url, fileData){
responseCount++;
allResponses[url] = fileData;
if(responseCount===config.sources.length){
allRequestsComplete(allResponses);
}
};
for (var eachSource = 0; eachSource < config.sources.length; eachSource++) {
(function(url){
allResponses[url] = "Waiting";
http.get({host: url,path: "/"}, function(response) {
response.on('error', function (chunk) {
requestComplete(url, "ERROR");
});
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
requestComplete(url, str);
});
});
}(config.sources[eachSource].replace(/ /g, "%20").replace("http://", "")));
}
}
});
`
I agree with #Kevin B, you cannot assume that async callbacks will return in the same order of which you send them. However, you could ensure the order, by adding an index function on processResponse.
say you add the following to addResult
addResult = function (index, url, value, timestamp) {
data[index] = {
value : value,
timestamp : timestamp,
url : url
};
numResults++;
if (numResults === config.sources.length) { //once all results are in build the output file
createOutputData();
}
}
and use an extra function to call your request
function doRequest(index, url) {
request(url, function(responseError, response, body) {
if (responseError) {
console.log(responseError);
} else {
parseXML(body, {
explicitArray : false
}, function (xmlError, result) {
if (xmlError) {
console.log(xmlError);
}
addResult(index, response.request.uri.href, result.Hilltop.Measurement.Data.E.I1, moment(result.Hilltop.Measurement.Data.E.T));
});
}
});
}
then you can also change your loop to:
for (eachSource = 0; eachSource < config.sources.length; eachSource++) {
config.sources[eachSource] = config.sources[eachSource].replace(/ /g, "%20"); //replace all %20 with " "
doRequest(eachSource, config.sources[eachSource]); //request each source
}