Mongoose: Fügen Sie dem Modellspeichervorgang den Rückgabewert „Promise“ hinzu

Erstellt am 16. Apr. 2013  ·  50Kommentare  ·  Quelle: Automattic/mongoose

Versprechungsrückgabeunterstützung hinzufügen, um Vorgang zu speichern, gibt derzeit undefiniert zurück. Je nach Validierung und Speicherstatus gibt es mehrere Rückgabepfade, die aktualisiert werden müssten. Dies würde eine Verkettung mehrerer Speicheroperationen mit .then() anstelle einer Verschachtelung ermöglichen.

enhancement

Hilfreichster Kommentar

Im Moment mache ich das:

userSchema.methods.saveAsync = function() {
  return new Promise((resolve,reject) => {
    this.save((err) => {
      if(err) return reject(err)
      resolve()
    })
  })
}

Alle 50 Kommentare

Ich füge dies der Liste für 4.x hinzu. Bezieht sich darauf, wie Middleware implementiert wird (hooks.js).

Super, danke. Ich habe eine Version von jquerys .when als Erweiterung des Mongoose Promise-Objekts für mein Projekt implementiert. Wären Sie daran interessiert, einen Pull-Request zu haben?

var p1 = Users.find ();
var p2 = Tiere.find();
Promise.when(p1, p2).addBack(function(err, users, animals) {
//etc
});

Nein Danke. Ich möchte wirklich keine weiteren Funktionen hinzufügen, die außerhalb von Mongoose implementiert werden können. Es ist schon aufgebläht.

Für andere, die diesen Thread finden, hier ist er: https://github.com/wshaver/mongoosewhen

@wshaver veröffentlichen Sie das in npm und fügen Sie ein Mungo-Tag hinzu, damit es auf http://plugins.mongoosejs.com angezeigt wird

Hierher verschoben, um der Verwendung von Bindestrichen im Namen anderer Mongoose-Plugins zu entsprechen: https://github.com/wshaver/mongoose-when

Auf npm veröffentlicht, getaggt. Erscheint noch nicht, aber vielleicht gibt es eine Verzögerung.

@wshaver cool. es wird einmal täglich aktualisiert.

Nachdem ich in # 1446 gegraben habe, denke ich, dass ich dies erreichen kann, ohne "hooks.js" zu entfernen.
Grünes Licht?

Tue es

Am Montag, den 7. Oktober 2013 schrieb Refael Ackermann:

Nachdem ich in # 1446 https://github.com/LearnBoost/mongoose/issues/1446 gegraben habe, denke ich, dass ich dies erreichen kann, ohne „hooks.js“ zu entfernen.
Grünes Licht?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHubhttps://github.com/LearnBoost/mongoose/issues/1431#issuecomment -25792310 an
.

Aaron
@aaronheckmann https://twitter.com/#!/aaronheckmann
soundcloud.com/ajhecky
github.com/aheckmann

Große PR bereit

Das würde mir auch sehr weiterhelfen. Es sollte möglich sein, myDoc.save().exec() aufzurufen - also sollte save im Grunde eine Abfrage zurückgeben, die ausgeführt werden kann. Oder was ist der Grund, dass Save keine Abfrage zurückgibt?

+1 für Rückrufversprechen, wenn wir den Rückruf weglassen

Der Fix befindet sich im master -Zweig, der in 3.10 enthalten sein soll.

Enthält dies ein zurückgegebenes Versprechen für den Modellerstellungsvorgang?

@GDownes create() gibt bereits ein Versprechen zurück :) http://mongoosejs.com/docs/api.html#model_Model.create

irgendein geplantes Veröffentlichungsdatum für 3.10? :)

@swayf 4.0 ist noch ein paar Monate draußen. Meine Linie im Sand ist der 2. September, aber hoffentlich vorher :)

Ist das noch für eine kommende Version geplant?

Ja, das wird in 4.0 sein, aber ich habe noch kein Veröffentlichungsdatum dafür. Die letzte Schätzung war nicht ganz richtig :(

:+1:

+1 weil:

Ich muss 2 Dokumente in einem Mokka-Test vor dem Hook speichern, und diese Funktionalität würde es mir ermöglichen, den done() -Rückruf auszuführen, sobald beide Modelle gespeichert sind.

Ich habe versucht, die Collection.insert([docs], done) -Methode zu verwenden, aber sie löst keine Schema.pre('save') -Logik aus, die ich brauche, um einige Werte zu hashen.

@arathael Sie können jederzeit das async -Modul verwenden, um Ihre beiden Dokumente in async.parallel zu speichern und im Callback done auszuführen

Danke Mann, das teste ich gerade. Ich bin einfach eingestiegen, weil ich denke, dass der native Support von ODM rocken würde.

+1

Ich verwende das experimentelle ES7 await/async mit 6to5. Wenn record.save() ein Versprechen zurückgegeben hat, kann ich Folgendes tun:

try {
  await record.save()
} catch(err) {
  ...
}

Im Moment mache ich das:

userSchema.methods.saveAsync = function() {
  return new Promise((resolve,reject) => {
    this.save((err) => {
      if(err) return reject(err)
      resolve()
    })
  })
}

+1 für @aaronshaf , funktioniert hervorragend für mich, ich würde es auch in ES5 für diejenigen schreiben, die ES6 nicht verwenden. Danke

Hier ist, was ich jetzt getan habe. Offensichtlich wird Q nicht benötigt, aber das verwende ich an anderer Stelle für Versprechungen.

/*
 * Hack until mongoose 3.10 comes out. See this: https://github.com/LearnBoost/mongoose/issues/1431
 */
mongoose.Document.prototype.savePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.save(function (err, item, numberAffected) {
            if (err) {
                reject(err);
            }
            resolve(item, numberAffected);
        });
    });
};

mongoose.Document.prototype.removePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.remove(function (err, item) {
            if (err) {
                reject(err);
            }
            resolve(item);
        });
    });
};

+1 auf dem Hack @jhullfly , aber ich denke, die Auflösung von Q nimmt nur ein Argument, sodass numberAffected gelöscht wird. Sie müssen sie in ein Array oder etwas einfügen, um Zugriff auf beide zu erhalten:

mongoose.Document.prototype.savePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.save(function (err, item, numberAffected) {
            if (err) {
                reject(err);
            }
            resolve([item, numberAffected]);
        });
    });
};

1+ für das Versprechen, das von save zurückgegeben wird!

Jetzt gibt save das Versprechen in 4.0.1 zurück. Beifall.

+1

@arathael +1

Gibt es Dokumentation zur Verwendung save mit Promises?

Ich habe folgendes versucht und es scheint nicht zu funktionieren:

var User = mongoose.model('User');
var u = new User();
u.save().then(function() {
// never gets here.
});
// I even tried the following, and neither works.
u.save().then(function() {}).end();

Sind Sie auf Mongoose 4.0.1 und haben Sie es mit npm installiert?

@Ouwen Ja, ich verwende 4.0.1 und ja, das habe ich getan, sonst hätte ich einen Fehler bekommen, wenn Mongoose nicht installiert wäre.

Das Problem ist, dass then scheinbar nie aufgerufen wird. Ich bin mir ziemlich sicher, dass ich etwas Seltsames mache (sonst würden schnell Fehler gemeldet), aber ich kann nicht begründen, was, deshalb bin ich neugierig, ob es Beispiele / Dokumentationen dazu gibt.

Hmm, sehr merkwürdig. Ich weiß, dass ich 3.8.8 ausgeführt habe und vergessen habe, npm install auf 4.0.1 zu aktualisieren, weshalb von u.save() kein Promise zurückgegeben wurde.

Was du geschrieben hast, sollte funktionieren.

@limianwang verbinden Sie sich erfolgreich mit einem Mongodb-Server? Können Sie mir ein eigenständiges Beispiel geben, das dies reproduziert?

Es scheint, dass das von .save() zurückgegebene Promise-Objekt nicht dasselbe ist wie andere Promises, es hat catch/caught statt onReject.

Mungo 4.1.10 und ...

var u = new User();
u.save().then(...)

gibt immer noch kein Versprechen zurück

@xrado Bitte geben Sie ein aussagekräftigeres Beispiel an. Wir haben Tests durchgeführt, um zu zeigen, dass dies in Mongoose 4.1.10 funktionieren sollte.

@vkarpov15 Mein Fehler, ich habe es noch einmal versucht und es funktioniert. Ich weiß nicht, was ich vorher gemacht habe. Entschuldigung

Ich habe das gleiche Problem, Save speichert die Daten sofort in der db und ruft den Code dann nicht auf. Das Seltsame ist, dass ich einen anderen Code hatte, der den damaligen Block aufrief und das Versprechen funktionierte.

Code (der Teil user.save() speichert ihn, wird dann nicht definiert, aber nie aufgerufen)

user.save().then( function(userX) { // Speichern funktioniert
Konsole.log(2); // Dies wird nicht aufgerufen
}).end() // nicht aufgerufen
.then(undefiniert, Funktion(err){
console.log('err:' + err ); // nicht aufgerufen
});

Update Ich habe die alte Methode verwendet und es funktioniert wie folgt:

user.save(Funktion (err, neuer Benutzer) {
if (err) console.log('err=' + err);
console.log('Benutzer gespeichert');
});

WTF: Die Lösung bestand darin, einfach die Version von Mongoose von "3.8.X" auf ^4.1.9 zu ändern.

Dann user.save().then( function(userX) { // save funktioniert
Konsole.log(2);
}).Ende()
.then(undefiniert, Funktion(err){
console.log('err:' + err );
});

FUNKTIONIERT!!!!!!!!!!! Süss....

@nickjohngray froh, dass du es herausgefunden hast :) Ich empfehle dir dringend, den Promises Guide in der Dokumentation zu lesen, bevor du weiterhin Promises mit Mungo verwendest – keine Sorge, es ist eine kurze Lektüre.

Ich habe das gleiche Problem ... Ich hoffe wirklich, dass ich nicht eine ganze Hauptversion herunterstufen muss, nur um eine Speicherung zu erhalten, die in einem Versprechen funktioniert.

@jhyland87 Bitte stellen Sie Codebeispiele bereit, damit ich sehen kann, was das Problem ist.

@ vkarpov15 habe ich im Ticket

Dies wurde in dem anderen Ticket behoben ...

Im Grunde dieser Code:

var User = mongoose.model('User');
var u = new User();
u.save().then(function() {
// never gets here.
});

Beim Speichern eines Dokuments musste nur ein return hinzugefügt werden. Also:

var User = mongoose.model('User');
var u = new User();
return u.save().then(function() {
// never gets here.
});

@jhyland87 , FYI – ein weiteres Beispiel für die Verkettung von Versprechen mit Mongoose .

Ist das immer noch ein Problem?

Ich habe den folgenden Code (mit TypeScript) ...

User.findById(id)
.exec()
.then((user) => {
  user.name = 'new name from wherever!';
  return user.save();
})
.then((user) => {
  // want to do more stuff with the user object once it has been saved successfully...
  // ... but it never makes it here!!!
};

Wenn ich jedoch der save() -Funktion einen leeren Rückruf hinzufüge, scheint alles in Ordnung zu sein, wie unten ...

User.findById(id)
.exec()
.then((user) => {
  user.name = 'new name from wherever!';
  return user.save(() => {
    // unwanted empty callback... hmmm?
  });
})
.then((user) => {
  // we made it here!!! but now...
  // user === undefined :(
};

Benutzt du mpromise? Versuchen Sie, zu mongoose.Promise = global.Promise; zu wechseln

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen