Ich bin ein Nodejs Anfänger und ich lief in ein Callback-Verhalten, das ich nicht verstehe. Ich verwende einen Express-Router, um Mongoose-Objekte mit einer POST-Anfrage in Mongodb zu schreiben. Im Rumpf der Anfrage gebe ich eine verschachtelte JSON-Struktur mit zwei Feldern ein - jobDetails
und examples
. Die Daten in jobDetails
werden verwendet, um ein Mungo-Objekt Job
zu erstellen, und die Daten in examples
werden verwendet, um mehrere Example
Mongoose-Objekte zu erstellen. Die Objekte Job
und Example
sind verknüpft, indem Job
eine Liste von Example
Objekten in einem seiner Felder enthält.Node.js Callback unerwartetes Verhalten mit Mongoose
Die Art, wie ich dies versuchte, war mit Rückrufen in der folgenden Weise. Grundsätzlich speichere ich zuerst das Job
Objekt zu Mongo, dann iteriere über die Beispiele - jedes Mal ein Example
Objekt erstellen und es über das Feld .job
mit dem Job verknüpfen und auch das Objekt Example
an Mongo speichern. Dann im Callback auf die Example
Objektspeicherfunktion habe ich das Objekt Job
mit dem neuen Objekt Example
aktualisiert und die aktualisierte Version auf Mongo gespeichert.
router.post('/jobs', function (req, res, next) {
var job = new Job(req.body.jobDetails);
var examples = req.body.examples;
console.log("JOB DETAILS");
console.log(req.body.jobDetails);
console.log("EXAMPLES");
console.log(req.body.examples);
//save job
job.save(function (err, job) {
console.log(err);
});
//save examples
for(i=0; i<examples.length;i++){
var eg = new Example({content: examples[i]});
eg.job=job;
eg.save(function (err, eg){
job.examples.push(eg);
job.save(function(err, job){
console.log(err);
});
console.log(err);
});
}
});
Dies lief nicht so, wie ich es erwarten würde. Genauer gesagt wurde die doppelte Anzahl von Beispielen tatsächlich in Mongo mit mehreren Duplikaten und einigen fehlenden gespeichert. Ich verstehe, dass Rückrufe asynchron sind, aber für mich erklärt das immer noch nicht, warum die doppelte Anzahl von Beispielen gespeichert würde und einige würden dupliziert werden und einige würden fehlen.
Ich habe es schließlich richtig funktionieren, ohne Rückrufe auf die folgende Weise überhaupt zu verwenden.
router.post('/jobs', function (req, res, next) {
var job = new Job(req.body.jobDetails);
var examples = req.body.examples;
console.log("JOB DETAILS");
console.log(req.body.jobDetails);
console.log("EXAMPLES");
console.log(req.body.examples);
//save job
job.save(function (err, job) {
console.log(err);
});
//save examples
for(i=0; i<examples.length;i++){
var eg = new Example({content: examples[i]});
eg.job=job;
eg.save(function (err, eg){
console.log(err);
});
job.examples.push(eg);
job.save(function(err,job){
console.log(err);
});
}
});
Und ich bin mir nicht sicher, ob dies auch die optimale Lösung ist. Aber ich würde gerne wissen, warum mein ursprünglicher Ansatz zu dem unbeabsichtigten Verhalten geführt hat. Speichervorgänge in einem Schritt für Schritt Weise
Sind Sie sicher über die 'job.save (function (err, job) { if (err) job.examples = [];! });' Teil? Sind damit nicht alle Beispiele klar? – user1893354
Hat es für Sie funktioniert? Diese Zeile löschte jedes Beispiel nach dem Speichern, dh es wird kein Duplikat hinzugefügt. – abdulbarik
aber alle Beispiele müssen in job.examples gespeichert werden. Wenn Sie die Beispiele nach jedem Job.save löschen, überschreibt dies nicht alle, die zuvor gespeichert wurden? – user1893354