Мангуст - Що виконує функція exec?


100

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

Я ніколи раніше не бачив цього методу в Javascript? Що саме робить?

Відповіді:


144

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

callback:

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

exec:

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

Тому, коли ви не передаєте зворотний виклик, ви можете побудувати запит і врешті виконати його.

Ви можете знайти додаткову інформацію в документах мангуста .

ОНОВЛЕННЯ

Щось, на що слід звернути увагу при використанні Promises у поєднанні з асинхронними операціями Mongoose, це те, що запити Mongoose не є Promises. Запити повертаються підданими , але якщо вам потрібна справжня Обіцянка, вам слід скористатися execметодом. Більше інформації можна знайти тут .

Під час оновлення я помітив, що я не відповідав прямо на питання:

Я ніколи раніше не бачив цього методу в Javascript? Що саме робить?

Ну це не рідний метод JavaScript, а частина API Mongoose.


4
Що робити, якщо я встановив mongoose.Promise = require ('bluebird'), чи все-таки мені потрібно використовувати .exec ()? Дякую.
— виходу

4
@wayofthefuture Я вважаю, що документи справді заплутані з цього приводу, але я вважаю, що вам все одно потрібно зателефонувати до execметоду. Це те, що вони роблять принаймні в документах. Щоб бути впевненим, що ви можете перевірити себе Model.find() instanceof require('bluebird'). Сподіваюся, це допомагає.
— danillouz

1
І тоді виникає питання про інші операції, такі як delete і insertMany ... чи буде в цих випадках необхідний exec ()? Delete мав би використовувати якийсь запит під капотом ...
— wayofthefuture

1
exec також повертає обіцянку, якщо не буде передано зворотний виклик, що дуже зручно, я повинен сказати
— Alexander Mills

Це може когось врятувати . Якщо ви думаєте, що Model.update () зробить свою справу, і не чекайте оновлення деяких не дуже важливих даних і повертайте відповідь на API; Ваше оновлення не буде запущено. Вам потрібно Model.update().exec()переконатися, що він буде виконаний. Тоді ви можете відповісти на api, не чекаючи оновлення.
— Йогеш

48

Даніель відповів на це досить красиво. Щоб детально розробити вичерпний перелік способів побудови та виконання запитів, перегляньте такі випадки використання:

Побудова запитів

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

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

Виконання за допомогою зворотного дзвінка

Хоча багатьом це не подобається через його вкладеність, запити можуть виконуватися шляхом надання необов’язкового зворотного виклику.

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

Потім API як Promises / A +

Запити мангуста дійсно надають 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працює в такому контексті.
— Аншул Кока,

[ПРИЙНЯТИ ВІДПОВІДЬ]
— Коді

Ви можете додати повний приклад із .exec ()? @AnshulKoka Це те, що .exec () автоматично робить запит асинхронним, або я повинен додати async / await
— O'Dane Brissett

Щоб зробити запит асинхронним, буде потрібно async / await, тому я не впевнений, що розумію питання. Просто префікс чекає мого прикладу для вашого запиту на повний приклад.
— Аншул Кока,

7

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.