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.