Mungo - Was macht die Exec-Funktion?

100

Ich bin auf einen Teil des Mongoose-Codes gestoßen, der eine Abfrage findOne und dann eine exec () -Funktion enthielt.

Ich habe diese Methode noch nie in Javascript gesehen? Was macht es genau?

user439133
quelle

Antworten:

143

Grundsätzlich können bei Verwendung von Mungo Dokumente mithilfe von Helfern abgerufen werden. Jede Modellmethode, die Abfragebedingungen akzeptiert, kann mit a callbackoder der execMethode ausgeführt werden.

callback::

User.findOne({ name: 'daniel' }, function (err, user) {
  //
});

exec::

User
  .findOne({ name: 'daniel' })
  .exec(function (err, user) {
      //
  });

Wenn Sie keinen Rückruf übergeben, können Sie daher eine Abfrage erstellen und schließlich ausführen.

Weitere Informationen finden Sie in den Mungo-Dokumenten .

AKTUALISIEREN

Bei der Verwendung von Promises in Kombination mit asynchronen Mongoose-Vorgängen ist zu beachten, dass es sich um Mongoose-Abfragen handelt keine Promises sind. Abfragen geben zwar ein thenable zurück , aber wenn Sie ein echtes Versprechen benötigen , sollten Sie die execMethode verwenden. Weitere Informationen finden Sie hier .

Während des Updates habe ich festgestellt, dass ich die Frage nicht explizit beantwortet habe:

Ich habe diese Methode noch nie in Javascript gesehen? Was macht es genau?

Also es ist keine native JavaScript-Methode, sondern Teil der Mongoose-API.

danillouz
quelle
4
Was ist, wenn ich mongoose.Promise = require ('bluebird') gesetzt habe? Muss ich trotzdem .exec () verwenden? Vielen Dank.
Wayofthefuture
4
@wayofthefuture Ich finde die Dokumente in dieser Angelegenheit wirklich verwirrend, aber ich glaube, Sie müssen die execMethode noch aufrufen . Dies ist, was sie zumindest in den Dokumenten tun. Um sicher zu sein, können Sie sich mit überprüfen Model.find() instanceof require('bluebird'). Hoffe das hilft.
Danillouz
1
Und dann ist da noch die Frage nach anderen Operationen wie delete und insertMany ... wäre exec () in diesen Fällen notwendig? Löschen müsste eine Art Abfrage unter der Haube verwenden ...
wayofthefuture
1
exec gibt auch ein Versprechen zurück, wenn kein Rückruf übergeben wird, was sehr praktisch ist, muss ich sagen
Alexander Mills
Es könnte jemanden retten . Wenn Sie der Meinung sind, dass Model.update () seine Aufgabe erfüllt und nicht darauf wartet, dass einige nicht so wichtige Daten aktualisiert werden, und eine Antwort an die API zurückgibt; Ihr Update wird nicht ausgeführt. Sie müssen Model.update().exec()sicherstellen, dass es ausgeführt wird. Dann können Sie auf die API antworten, ohne auf ein Update zu warten.
Yogesh
48

Daniel hat das sehr schön beantwortet. Sehen Sie sich die folgenden Anwendungsfälle an, um eine vollständige Liste der Möglichkeiten zum Erstellen und Ausführen von Abfragen zu erstellen:

Abfrageerstellung

Mungo führt eine Abfrage erst aus , wenn sie aufgerufen wurde thenoder execaufgerufen wurde. Dies ist sehr nützlich, wenn Sie komplexe Abfragen erstellen. Einige Beispiele können die Verwendung der Funktionen populateund umfassen aggregate.

User.find({name: 'John'}) // Will not execute

Ausführung per Rückruf

Obwohl dies aufgrund seiner Verschachtelung von vielen nicht gemocht wird, können Abfragen ausgeführt werden, indem der optionale Rückruf bereitgestellt wird.

User.find({name: 'John'}, (err, res) => {}) // Will execute

Dann API als Versprechen / A +

Mungo-Abfragen bieten eine thenFunktion. Dies ist nicht mit regelmäßigen Versprechungen zu verwechseln. Einfach ausgedrückt, erfordert die Promises / A + -Spezifikation eine thenFunktion, die so funktioniert, wie wir es mit Versprechungen gewohnt sind.

User.find({name: 'John'}).then(); // Will execute
Promise.all([User.find({name: 'John'}), User.find({name: 'Bob'})]) // Will execute all queries in parallel

Die Exec-Funktion

Aus Mungo-Dokumenten If you need a fully-fledged promise, use the .exec() function.

User.find({name: 'John'}).exec(); // Will execute returning a promise
Anshul Koka
quelle
1
Die Dokumente haben es nicht explizit erwähnt, aber die Beispiele zeigen, dass User.save () ebenfalls ein Versprechen zurückgibt. Abgesehen von exec () und save () geben andere Mungo-Methoden des Modells ein Versprechen zurück, oder sind es nur diese beiden?
Thetrystero
Wie oben erwähnt, können Sie thenbei einer Abfrage auch ein Versprechen zurückgeben. Das ist nicht viel anders als exec. Der Anwendungsfall, den ich praktisch finde, ist, wenn ich so etwas benutze Promise.all. Ich bin mir nicht sicher, ob das von diesen zurückgegebene Versprechen execin solchen Kontexten funktioniert.
Anshul Koka
[AKZEPTIERTE ANTWORT]
Cody
Können Sie bitte ein vollständiges Beispiel mit .exec () hinzufügen? @AnshulKoka Ist es so, dass die .exec () die Abfrage automatisch asynchron macht oder sollte ich async / await hinzufügen
O'Dane Brissett
Um die Abfrage asynchron zu machen, ist async / await erforderlich, daher bin ich mir nicht sicher, ob ich die Frage verstehe. Warten Sie einfach auf mein Beispiel, bevor Sie ein vollständiges Beispiel anfordern.
Anshul Koka
7

exec()wird ein Versprechen zurückgeben, wenn kein Rückruf erfolgt. Das folgende Muster ist also sehr praktisch und allgemein gehalten - es kann Rückrufe oder Versprechen gut verarbeiten:

function findAll(query, populate, cb) {

  let q = Response.find(query);

  if (populate && populate.length > 0) {
    q = q.populate(populate);
  }

  // cb is optional, will return promise if cb == null
  return q.lean().exec(cb);

}

Ich empfehle, Bluebird-Versprechen mit Mongoose zu verwenden. Verwenden Sie dazu diesen Aufruf:

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
Alexander Mills
quelle
Warum brauchen wir Bluebird? wenn wir exec () haben
Indraraj26