Mongoose - Cosa fa la funzione exec?


100

Mi sono imbattuto in un pezzo di codice Mongoose che includeva una query findOne e quindi una funzione exec ().

Non ho mai visto quel metodo in Javascript prima? Cosa fa esattamente?

Risposte:


144

Fondamentalmente quando si utilizza la mangusta, i documenti possono essere recuperati utilizzando gli helper. Ogni metodo di modello che accetta condizioni di query può essere eseguito mediante un metodo callbacko exec.

callback:

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

exec:

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

Pertanto, quando non si passa una richiamata, è possibile creare una query ed eventualmente eseguirla.

Puoi trovare ulteriori informazioni nei documenti di mongoose .

AGGIORNARE

Qualcosa da notare quando si utilizza Promises in combinazione con operazioni asincrone Mongoose è che le query Mongoose non sono Promesse. Le query restituiscono una tabella , ma se hai bisogno di una vera promessa dovresti usare il execmetodo. Ulteriori informazioni possono essere trovate qui .

Durante l'aggiornamento ho notato di non aver risposto esplicitamente alla domanda:

Non ho mai visto quel metodo in Javascript prima? Cosa fa esattamente?

Beh, non è un metodo JavaScript nativo, ma parte dell'API Mongoose.


4
E se ho impostato mongoose.Promise = require ('bluebird'), devo ancora usare .exec ()? Grazie.
futuro

4
@wayofthefuture Trovo i documenti davvero confusi su questo argomento, ma credo che sia ancora necessario chiamare il execmetodo. Questo è almeno quello che fanno nei documenti. Per essere sicuro puoi controllare tu stesso con Model.find() instanceof require('bluebird'). Spero che questo ti aiuti.
danillouz

1
E poi c'è la questione di altre operazioni come delete e insertMany ... exec () sarebbe necessario in questi casi? L'eliminazione dovrebbe utilizzare una sorta di query sotto il cofano ...
wayofthefuturo

1
exec restituisce anche una promessa, se non viene superata la richiamata, il che è molto conveniente, devo dire
Alexander Mills

Potrebbe salvare qualcuno . Se pensi che Model.update () farà il suo lavoro e non aspettare che alcuni dati non così importanti vengano aggiornati e restituiscano la risposta all'API; Il tuo aggiornamento non verrà eseguito. Devi Model.update().exec()assicurarti che venga eseguito. Quindi puoi rispondere all'API senza attendere l'aggiornamento.
Yogesh

48

Daniel ha risposto in modo molto bello. Per elaborare un elenco esaustivo di modi per creare ed eseguire query, guarda i seguenti casi d'uso:

Creazione di query

Mongoose non eseguirà una query fino a quando theno execè stato chiamato su di essa. Questo è molto utile quando si creano query complesse. Alcuni esempi possono includere l'utilizzo delle funzioni populatee aggregate.

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

Esecuzione tramite callback

Sebbene non piaccia a molti a causa della sua natura di nidificazione, le query possono essere eseguite fornendo la richiamata opzionale.

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

Quindi API come promesse / A +

Le query Mongoose forniscono una thenfunzione. Questo non deve essere confuso con promesse regolari. In poche parole, la specifica Promises / A + richiede una thenfunzione che funzioni in modo molto simile a come siamo abituati alle promesse.

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

La funzione exec

Dai documenti di Mongoose If you need a fully-fledged promise, use the .exec() function.

User.find({name: 'John'}).exec(); // Will execute returning a promise

1
i documenti non lo menzionano esplicitamente ma gli esempi mostrano anche User.save () che restituisce una promessa. A parte exec () e save () altri metodi mongoose sul modello restituiscono una promessa, o sono solo questi due?
thetrystero

Come accennato in precedenza, puoi utilizzare thensu una query anche per restituire una promessa. Questo non è molto diverso da exec. Il caso d'uso che trovo utile è quando si usa qualcosa di simile Promise.all. Non sono sicuro se la promessa restituita da execfunziona in tali contesti però.
Anshul Koka

[RISPOSTA ACCETTATA]
Cody

Puoi aggiungere un esempio completo con .exec ()? @AnshulKoka È che .exec () rende automaticamente la query asincrona o dovrei aggiungere async / await
O'Dane Brissett,

Rendere la query asincrona richiederà async / await, quindi non sono sicuro di aver capito la domanda. Attendo solo il prefisso del mio esempio per la tua richiesta di un esempio completo.
Anshul Koka,

7

exec()restituirà una promessa se non viene fornita alcuna richiamata. Quindi il seguente schema è molto comodo e generico: può gestire bene i callback o le promesse:

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);

}

Consiglio di utilizzare le promesse di Bluebird con Mongoose, per farlo, usa questa chiamata:

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

perché abbiamo bisogno di bluebird? quando abbiamo exec ()
Indraraj26
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.