2016-04-29 14 views
0

Ich muss Datensätze in zwei Sammlungen einfügen. Die zweite Sammlung speichert die ID der Datensätze der ersten Sammlung. Es ist eine 1: m (fistert: zweite) Situation. Der Auslöser ist die zweite Kollektion:Mongoose: Fügen Sie eine Sammlung von einer anderen mit Versprechen

  1. Wenn ein Datensatz für die zweite Sammlung benötigt
  2. Prüfung abgelegt werden, wenn bereits ein passender Datensatz in der ersten Kollektion
  3. wenn nicht: dann eine in dem Speicher erste Kollektion
  4. speichern die zweite Kollektion
  5. die ID des Datensatzes der ersten Sammlung in der zweiten Sammlung speichern

Das folgende Beispiel scheint diese Schritte zu erfüllen. Aber ich habe die Versprechungen nur auf halbem Wege. Wie kann dies besser "versprochen" werden?

saveObjects(name: String, objects: Array<IObject>){ 

     var promise = FirstModel.findOne({Name : name}).exec(); 
     promise.then(function(res1){ 
      if (!res1){ 
       var la = new FirstModel(); 
       la.Name = name; 
       la.save(function(err){ 
        if (err) throw err; 
       }) 
      } 
     }).error(function(err){ 
      throw err; 
     }) 

     objects.forEach(function(obj) { 
      FirstModel.findOne({Name : name},'_id',function(err, res2){ 
       if (err) throw err; 

       var vo = new SecondModel(); 
       vo.Name = name; 
       vo.FistID = res2._id; 

       vo.save(function(err){ 
        if (err) throw err; 
       }); 
      }); 
     }); 

} 

Antwort

0

Ich bin gona hier davon ausgehen, dass Sie drossel verwenden oder ein anderes Versprechen Äquivalent einzurichten.

var Promise = require('bluebird'); 
saveObjects(name: String, objects: Array <IObject>) { 

    // Get the first model 
    return FirstModel 
     .findOne({ 
      Name: name 
     }) 
     .exec() 
     .then(function (res1) { 
      if (!res1) { 
       var la = new FirstModel(); 
       la.Name = name; 
       return la.save() // We return the save operation on the model, save() returns a promise 
      } 

      // We just return the model normally so it passes down the chain. 
      return res1; 
     }) 
     .then(function (res1) { 
      // Here we use Promise.all() method on bluebird which accepts an Array 
      // of promises, we create a promise from the objects array by using Array.map() which 
      // goes through every object in the array and creates a new array. 
      return Promise 
       .all(objects.map(function (obj) { 
        // We go through each object in objects and create a new 
        // model and return the save() method of each model, this 
        // creates a array of promises which are resolved when each 
        // all model has been saved. 
        var vo = new SecondModel(); 
        vo.Name = name; 
        vo.FistID = res1._id; 

        return vo.save(); 
       })); 
     }) 
     .then(function (models) { 
      // here we have all the models we just saved in an array called models, 
      // do what you want with it. 
     }) 
     .error(function (err) { 
      throw err; 
     }) 
} 

Für weitere Informationen siehe Dokumentation auf Array.map() here und Promise.all() here

+0

Aber die Referenz 'vo.FistID = res1._id;' zum FirstModel, wirft anerror in dem obigen Beispiel, da res1._id nicht in der ist Bereich im .then Teil. Aus diesem Grund habe ich an diesem Ort eine weitere Lektüre von FirstModel gemacht. Gibt es einen besseren Weg, dies zu tun? – MBushveld

+0

res1 ist in der zweiten then() definiert, so sollte es gut funktionieren. Wir übergeben Res1 von der ersten() zu der zweiten. Wenn Sie einen Fehler bekommen, fügen Sie ihn hier ein, damit ich sehen kann, was es ist. Wenn Sie direkt kopieren/einfügen, sollten Sie wissen, dass ich gerade einen kleinen Syntaxfehler behoben habe, so dass Sie es erneut versuchen sollten. – grimurd

+0

Der Fehler, den ich bekomme, ist 'error TS2339: Eigenschaft '_id' existiert nicht am Typ '{}'. Dies scheint für mich zu sein, dass res1 im zweiten Teil nicht bekannt ist. – MBushveld

Verwandte Themen