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.