Mongoose - O que a função exec faz?


100

Me deparei com um trecho de código do Mongoose que incluía uma consulta findOne e uma função exec ().

Nunca vi esse método em Javascript antes? O que isso faz exatamente?

Respostas:


144

Basicamente, ao usar o mangusto, os documentos podem ser recuperados usando ajudantes. Todo método de modelo que aceita condições de consulta pode ser executado por meio de um callbackou do execmétodo.

callback:

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

exec:

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

Portanto, quando você não passa um retorno de chamada, você pode construir uma consulta e eventualmente executá-la.

Você pode encontrar informações adicionais nos documentos do mangusto .

ATUALIZAR

Algo a ser observado ao usar Promises em combinação com operações assíncronas do Mongoose é que as consultas do Mongoose não são Promises. As consultas retornam um thenable , mas se você precisa de uma promessa real, deve usar o execmétodo. Mais informações podem ser encontradas aqui .

Durante a atualização, percebi que não respondi explicitamente à pergunta:

Nunca vi esse método em Javascript antes? O que isso faz exatamente?

Bem, não é um método nativo de JavaScript, mas parte da API Mongoose.


4
E se eu configurar mongoose.Promise = require ('bluebird'), ainda preciso usar .exec ()? Obrigado.
caminho do futuro

4
@wayofthefuture Acho a documentação muito confusa sobre esse assunto, mas acredito que você ainda precise chamar o execmétodo. Isso é o que eles fazem nos documentos, pelo menos. Para ter certeza, você pode verificar a si mesmo com Model.find() instanceof require('bluebird'). Espero que isto ajude.
danillouz

1
E depois há a questão de outras operações como delete e insertMany ... exec () seria necessário nesses casos? Delete teria que usar algum tipo de consulta por baixo do capô ...
wayofthefuture

1
exec também retorna uma promessa, se nenhum retorno de chamada for passado, o que é muito conveniente, devo dizer
Alexander Mills

Isso pode salvar alguém . Se você acha que Model.update () fará seu trabalho e não espere que alguns dados não tão importantes sejam atualizados e retornem uma resposta à API; Sua atualização não será executada. Você precisa Model.update().exec()ter certeza de que ele será executado. Então você pode responder à API sem esperar pela atualização.
Yogesh de

48

Daniel respondeu a isso muito bem. Para elaborar uma lista exaustiva de maneiras de criar e executar consultas, observe os seguintes casos de uso:

Construção de consulta

O Mongoose não executará uma consulta até thenou até execser chamado. Isso é muito útil ao construir consultas complexas. Alguns exemplos podem incluir o uso das funções populatee aggregate.

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

Execução via callback

Embora não sejam apreciadas por muitos devido à sua natureza de aninhamento, as consultas podem ser executadas fornecendo o retorno de chamada opcional.

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

Então API as a Promises / A +

As consultas do Mongoose fornecem uma thenfunção. Isso não deve ser confundido com promessas regulares. Simplificando, a especificação Promises / A + requer uma thenfunção para funcionar da mesma forma que estamos acostumados com promessas.

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

A função exec

Da documentação da Mongoose If you need a fully-fledged promise, use the .exec() function.

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

1
os documentos não mencionaram explicitamente, mas os exemplos mostram User.save () retornando uma promessa também. Além de exec () e save (), algum outro método mongoose no modelo retorna uma promessa ou são apenas esses dois?
thetrystero

Como apontado acima, você também pode usar thenem uma consulta para retornar uma promessa. Isso não é muito diferente de exec. O caso de uso que considero útil é quando uso algo como Promise.all. Não tenho certeza se a promessa retornada por execfunciona em tais contextos embora.
Anshul Koka,

[RESPOSTA ACEITA]
Cody

Você pode adicionar um exemplo completo com .exec ()? @AnshulKoka É que o .exec () automaticamente torna a consulta assíncrona ou devo adicionar async /
await

Tornar a consulta assíncrona exigirá async / await, então não tenho certeza se entendi a pergunta. Apenas prefixo aguardar meu exemplo para seu pedido de um exemplo completo.
Anshul Koka

7

exec()retornará uma promessa se nenhum retorno de chamada for fornecido. Portanto, o seguinte padrão é muito conveniente e genérico - ele pode lidar bem com retornos de chamada ou promessas:

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

}

Eu recomendo usar promessas do Bluebird com Mongoose, para fazer isso, use esta chamada:

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

por que precisamos do bluebird? quando temos exec ()
Indraraj26
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.