Ich möchte eine Funktion aufrufen, die Daten für jeden Schüler für ein bestimmtes Zeitintervall dauert und den gleichen Prozess wiederholen, bis es eine Bedingung erreicht.Wie schreibe ich eine synchrone While-Schleife mit node.js und Versprechen
Der aktuelle Code scheint parallele Aufrufe an die Funktion iterateThruAllStudents();
Mein Code sieht wie folgt aus:
var startDate = new Date("March 16, 2016 00:00:00"); //Start from February
var fromTimestamp = null;
var toTimestamp = null;
var today = new Date();
var todayTimestamp = new Date(today).getTime()/1000;
async.whilst(
function() {
return fromTimestamp < todayTimestamp;
},
function (callback) {
console.log(startDate);
fromTimestamp = new Date(startDate).getTime()/1000;
startDate.setDate(startDate.getDate() + 5);
toTimestamp = new Date(startDate).getTime()/1000;
iterateThruAllStudents(fromTimestamp, toTimestamp);
callback(null, startDate);
},
function (err, n) {
console.log('finished for ' + n);
}
);
function iterateThruAllStudents(from, to) {
Student.find({status: 'student'})
.populate('user')
.exec(function (err, students) {
if (err) {
throw err;
}
var counter = 0;
async.eachSeries(students, function iteratee(student, callback) {
if (student.worksnap.user != null) {
var worksnapOptions = {
hostname: 'api.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 ' + auth_hash
},
method: 'GET'
};
getTimeEntries(worksnapOptions)
.then(function (response) { //callback invoked on deferred.resolve
return convertXMLToJson(response);
}).then(function (timeEntries) {
console.log('convert xml to json');
var isEmpty = _.isEmpty(timeEntries); // true
if (isEmpty) {
callback(null);
}
return saveTimeEntry(timeEntries);
}).then(function (response) {
counter++;
console.log('all timeEntries for one student finished....Student: ' + student.worksnap.user.user_id + ' Student Counter: ' + counter);
callback(null);
});
} else {
callback(null);
}
});
});
}
function convertXMLToJson(response) {
var deferred = Q.defer();
parser.parseString(response, function (err, results) {
if (err) {
deferred.reject(err);
}
var json_string = JSON.stringify(results.time_entries);
var timeEntries = JSON.parse(json_string);
deferred.resolve(timeEntries);
});
return deferred.promise;
}
function saveTimeEntry(timeEntries) {
var deferred = Q.defer();
_.forEach(timeEntries.time_entry, function (item) {
Student.findOne({
'worksnap.user.user_id': item.user_id[0]
})
.populate('user')
.exec(function (err, student) {
if (err) {
deferred.reject(err);
}
student.worksnap.timeEntries.push(item);
student.save(function (err) {
if (err) {
deferred.reject(err);
} else {
//console.log(item);
}
});
});
});
deferred.resolve('finished saving timeEntries for one student...');
return deferred.promise;
}
function getTimeEntries(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
console.log('inside On error.');
console.log(err);
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;
}
jemand eine Idee hat, wie man so etwas zu erreichen, die ich Daten für alle Schüler synchron für jedes Zeitintervall greifen?
Es ist nicht ganz klar, warum Ihr aktueller Code nicht funktioniert. Bitte versuchen Sie auch, ein [mcve] zur Verfügung zu stellen. Entfernen Sie jeglichen Code, der für Ihre Frage nicht relevant ist. – Shelvacu
Ich denke, Sie müssen Callback an "iterateThruAllStudents" übergeben und es den Rückruf aufrufen, wenn es fertig ist – stefreak
@stefreak Ich dachte etwas ähnliches, aber ich war nur nicht sicher, wo der Callback die Funktion sagen, dass der Prozess getan wird. Könnten Sie mir eine Probe geben? –