machen Ich möchte durch eine Reihe von Studenten iterieren und machen HTTP-Aufruf für jeden von ihnen und analysieren die Antwort und einfügen in mongodb, so würde ich dies für tun möchten jeder Schüler nacheinander bis alle Daten eingeschoben sind, fahre mit dem nächsten fort, so dass es besser für CPU und RAM wäre Speicher ...wie synchrone HTTP-Aufrufe mit Versprechungen in node.js
Bisher mache ich das, aber das ist aus irgendeinem Grund nicht was ich wollte ...
var startDate = new Date("February 20, 2016 00:00:00"); //Start from February
var from = new Date(startDate).getTime()/1000;
startDate.setDate(startDate.getDate() + 30);
var to = new Date(startDate).getTime()/1000;
iterateThruAllStudents(from, to);
function iterateThruAllStudents(from, to) {
Student.find({status: 'student'})
.populate('user')
.exec(function (err, students) {
if (err) {
throw err;
}
async.eachSeries(students, function iteratee(student, callback) {
if (student.worksnap.user != null) {
var worksnapOptions = {
hostname: 'worksnaps.com',
path: '/api/projects/' + project_id + '/time_entries.xml?user_ids=' + student.worksnap.user.user_id + '&from_timestamp=' + from + '&to_timestamp=' + to,
headers: {
'Authorization': 'Basic xxx='
},
method: 'GET'
};
promisedRequest(worksnapOptions)
.then(function (response) { //callback invoked on deferred.resolve
parser.parseString(response, function (err, results) {
var json_string = JSON.stringify(results.time_entries);
var timeEntries = JSON.parse(json_string);
_.forEach(timeEntries, function (timeEntry) {
_.forEach(timeEntry, function (item) {
saveTimeEntry(item);
});
});
callback(null);
});
}, function (newsError) { //callback invoked on deferred.reject
console.log(newsError);
});
}
});
});
}
function saveTimeEntry(item) {
Student.findOne({
'worksnap.user.user_id': item.user_id[0]
})
.populate('user')
.exec(function (err, student) {
if (err) {
throw err;
}
student.timeEntries.push(item);
student.save(function (err) {
if (err) {
console.log(err);
} else {
console.log(Math.random());
}
});
});
}
function promisedRequest(requestOptions) {
//create a deferred object from Q
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var deferred = Q.defer();
var req = http.request(requestOptions, function (response) {
//set the response encoding to parse json string
response.setEncoding('utf8');
var responseData = '';
//append data to responseData variable on the 'data' event emission
response.on('data', function (data) {
responseData += data;
});
//listen to the 'end' event
response.on('end', function() {
//resolve the deferred object with the response
console.log('http call finished');
deferred.resolve(responseData);
});
});
//listen to the 'error' event
req.on('error', function (err) {
//if an error occurs reject the deferred
deferred.reject(err);
});
req.end();
//we are returning a promise object
//if we returned the deferred object
//deferred object reject and resolve could potentially be modified
//violating the expected behavior of this function
return deferred.promise;
}
Es scheint auch, dass die saveEntry() innerhalb .then wird sofort für alle Schüler aufgerufen wird, und das scheint problematisch.
Ich bin neu in Javascript besonders wenn es um Versprechen kommt, Rückrufe ... jemand eine Idee zu erreichen, so etwas hat ...
Was ist 'parser.parseString()'? Ist das eine synchrone oder asynchrone Operation? – jfriend00
Sie sollten auch wissen, dass die Verwendung von 'throw' innerhalb eines asynchronen Callbacks absolut nicht gut ist, es sei denn, es befindet sich in einem' 'then()' Handler. Es wirft sich einfach in die Eingeweide einer asynchronen Operation zurück und Sie können es nie irgendwo finden. Verwenden Sie in diesem Fall keinen Wurf. – jfriend00
Warum auch '_.forEach (timeEntry)'? Was ist an diesem Punkt "timeEntry"? – jfriend00