2015-07-21 3 views
34

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

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

+2

вы читали документы мангуста? Это не родной метод JS, если вы имеете в виду это. – Bergi

ответ

46

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

callback:

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

exec:

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

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

Дополнительную информацию можно найти в mongoose docs.

UPDATE

Что-то следует обратить внимание при использовании Promises в сочетании с Mongoose асинхронными операциями является то, что Mongoose запросы не Promises. Запросы возвращают thenable, но если вам нужен real Promise вы должны использовать метод exec. Более подробную информацию можно найти here.

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

Я никогда не видел этого метода в JavaScript, прежде? Что он делает точно?

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

+2

Что делать, если я установил mongoose.Promise = require ('bluebird'), мне все еще нужно использовать .exec()? Благодарю. – wayofthefuture

+4

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

+1

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

13

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

запросов Строительство

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 

ехес функция

От Mongoose Docs If you need a fully-fledged promise, use the .exec() function.

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

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

+0

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

5

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'); 
Смежные вопросы