Мангуст - что делает функция exec?


101

Я наткнулся на фрагмент кода Mongoose, который включал запрос findOne, а затем функцию exec ().

Я никогда раньше не видел этот метод в Javascript? Что именно он делает?

Ответы:


147

Обычно при использовании мангуста документы можно получить с помощью помощников. Каждый метод модели, который принимает условия запроса, может быть выполнен с помощью метода callbackили execметода.

callback:

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

exec:

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

Поэтому, когда вы не передаете обратный вызов, вы можете создать запрос и в конечном итоге выполнить его.

Вы можете найти дополнительную информацию в документации мангуста .

ОБНОВИТЬ

При использовании обещаний в сочетании с асинхронными операциями Mongoose следует отметить, что запросы Mongoose не являются обещаниями. Запросы действительно возвращают значение , но если вам нужно настоящее обещание, вы должны использовать этот execметод. Более подробную информацию можно найти здесь .

Во время обновления я заметил, что не ответил прямо на вопрос:

Я никогда раньше не видел этот метод в Javascript? Что именно он делает?

Ну, это не собственный метод JavaScript, а часть API Mongoose.


4
Что, если я установил mongoose.Promise = require ('bluebird'), мне все равно нужно использовать .exec ()? Спасибо.
— wayofthefuture

4
@wayofthefuture Я считаю, что документы действительно сбивают с толку по этому поводу, но я считаю, что вам все равно нужно вызывать execметод. По крайней мере, это то, что они делают в документации. Конечно, вы можете проверить себя с помощью Model.find() instanceof require('bluebird'). Надеюсь это поможет.
— danillouz

1
И тогда возникает вопрос о других операциях, таких как delete и insertMany ... будет ли в этих случаях необходима функция exec ()? Удалить придется использовать какой-то запрос под капотом ...
— wayofthefuture

1
exec также возвращает обещание, если обратный вызов не передан, что, я должен сказать, очень удобно,
— Александр Миллс

Это может кого-то спасти . Если вы думаете, что Model.update () выполнит свою работу и не дожидаетесь обновления некоторых не очень важных данных и не вернете ответ API; Ваше обновление не будет выполнено. Вам нужно Model.update().exec()убедиться, что он будет выполнен. Затем вы можете ответить на api, не дожидаясь обновления.
— Йогеш

49

Дэниел ответил на это довольно красиво. Чтобы разработать исчерпывающий список способов построения и выполнения запросов, рассмотрите следующие варианты использования:

Построение запросов

Mongoose не выполнит запрос до тех пор , thenили execбыла вызвана на него. Это очень полезно при построении сложных запросов. Некоторые примеры могут включать в себя , используя populateи aggregateфункции.

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

Выполнение через обратный вызов

Хотя это не нравится многим из-за его вложенности, запросы можно выполнять, предоставляя дополнительный обратный вызов.

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

Тогда API как обещание / A +

Запросы Mongoose действительно предоставляют thenфункцию. Это не следует путать с обычными обещаниями. Проще говоря, спецификация Promises / A + требует, чтобы thenфункция работала так же, как мы привыкли с обещаниями.

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

Функция exec

Из документации Mongoose If you need a fully-fledged promise, use the .exec() function.

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

1
в документации это не упоминается явно, но в примерах показано, что User.save () также возвращает обещание. Помимо exec () и save (), какие-либо другие методы мангуста в модели возвращают обещание, или это только эти два?
— thetrystero

Как указано выше, вы также можете использовать thenзапрос для возврата обещания. Это не сильно отличается от exec. Вариант использования, который я считаю удобным, - это использование чего-то вроде Promise.all. Не уверен, что обещание, возвращаемое функцией, execработает в таких контекстах.
— Аншул Кока 05

[ПРИНЯТ ОТВЕТ]
— Коди,

Не могли бы вы добавить полный пример с .exec ()? @AnshulKoka Это то, что .exec () автоматически делает запрос асинхронным, или я должен добавить async / await
— О'Дейн Бриссетт,

Для выполнения асинхронного запроса потребуется async / await, поэтому я не уверен, понимаю ли я вопрос. Просто префикс ждите моего примера для вашего запроса для полного примера.
— Аншул Кока

8

exec()вернет обещание, если обратный вызов не предоставлен. Таким образом, следующий шаблон очень удобен и универсален - он отлично справляется с обратными вызовами или обещаниями:

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

}

Я рекомендую использовать обещания Bluebird с Mongoose, для этого используйте этот вызов:

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

зачем нам синяя птица? когда у нас есть exec ()
— Indraraj26
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.