2016-08-18 5 views
0

Ich konnte keine einfache for-Schleife verwenden, da request.save eine Funktion ist. Also habe ich forEach versucht. Es funktioniert perfekt! Bis ich den request.save Teil hinzufüge und ich die folgende Fehlermeldung erhalte, die meine App unterbricht.Iterate speichern in Node.JS über ein Array

Fehler: Header können nach dem Senden nicht festgelegt werden.

exports.submit = function (req, res) { 


    Person.find({ 
     cellPhone: req.body.phone 
    }).exec(function (err, people) { 
     people.forEach(saveRequest); 
    } 

    function saveRequest(item, index) { 

     var request = new Requests(); 
     request.start = req.body.start.value; 
     request.finish = req.body.finish.value; 
     request.phone = req.body.phone; 
     request.offDay = req.body.date; 

     request.user = people[index]._id; 
     request.name = people[index].name; 
     request.group = people[index].group; 

     request.save(function (err) { 
      if (err) { 
      console.log('request.save'); 
      return res.status(400); 
      } else { 
      // Remove sensitive data before login 
      //user.password = undefined; 
      //user.salt = undefined; 
      console.log(request); 
      res.json(request); 
      } 
     }); 
    } 
}); 
+0

Sie können 'res.json' nicht mehrmals aufrufen, Sie sollten res.write verwenden. Da das Speichern asynchron ist, denke ich, das Beste ist, Promise –

+0

Danke zu verwenden! Wie sollte der Code aussehen? Ich habe versucht res.writeHead (200, {'Content-Type': 'text/plain'}); und ich habe versucht, res.write (200, {'Content-Type': 'text/plain'}); mehrere Male und sie beide die App gebrochen. –

Antwort

1

Das Problem ist, wenn Sie die .save() durchführen Sie eine anonyme Funktion übergeben, die die Antwort im Fehlerfall abzuschließen.

Sie beenden also den ersten Speicherfehler.

Sie sollten die Antwort außerhalb des Rückrufs speichern.

Vielleicht verwenden Sie Ereignisse, um Ihren Code oder besser die Generatoren zu synchronisieren.

Bevor Sie foreach-Schleife:

let savedResponses = []; 
let savedErrors = []; 
... 

Dann wird Ihr savedRequest:

function saveRequest(item, index) { 

    var request = new Requests(); 
    request.start = req.body.start.value; 
    request.finish = req.body.finish.value; 
    request.phone = req.body.phone; 
    request.offDay = req.body.date; 

    request.user = people[index]._id; 
    request.name = people[index].name; 
    request.group = people[index].group; 

    request.save(function (err) { 
     if (err) { 
      console.log('request.save error'); 
      savedErrors.push(err); 
      // return res.status(400); 
     } else { 
      // Remove sensitive data before login 
      //user.password = undefined; 
      //user.salt = undefined; 
      console.log(request); 
      savedResponses.push(request); 

     } 
    }); 

} 

Dann nach der foreach-Schleife, sollten Sie das Ende des asynchronen Personal in der .save warten() Rückrufe.

Sie könnten das Ereignis Paket oder die Generatoren oder das Versprechen Muster verwenden.

Es hängt von der Version Ihres Knotens ab.

Wenn Sie den Code synched haben könnten Sie einfach Ihre Antwort vervollständigen zuerst auf Fehler überprüft:

if (savedErrors.length > 0) { 
    res.status = 400; 
    // ... report errors 
} 

Oder füllen Sie einfach die Antwort mit den savedResponses.

+0

Ich werde die Antwort in meiner Speicherfunktion löschen und fügen Sie es direkt nach foreach –

+0

Wenn Sie das tun, haben Sie keine Garantie, dass alle speichert durchgeführt wird, da es ** asynchron ist **. Wie ich im Kommentar sagte, sollten Sie auf jeden Fall Promises mit 'Promise.all' verwenden. –

+0

@ oliv37 Ich schrieb es in meiner Antwort, dass der asynchrone Teil in irgendeiner Weise behandelt werden sollte. –