2015-07-21 394 views
34

我遇到了一個包含查詢findOne和exec()函數的Mongoose代碼。Mongoose - exec函數的作用是什麼?

我從來沒有在Javascript中見過這種方法嗎?它究竟做了什麼?

+2

你讀過貓鼬的文檔?這不是一個原生的JS方法,如果你是這個意思。 – Bergi

回答

46

基本上當使用貓鼬時,可以使用助手來檢索文檔。接受查詢條件的每種模型方法都可以通過callbackexec方法執行。

callback

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

exec

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

因此,當你不及格,你可以建立一個查詢,並最終執行它的回調。

你可以在mongoose docs找到更多的信息。

UPDATE

東西與貓鼬異步操作組合使用Promises時需要注意的是,貓鼬查詢是承諾。查詢確實返回,然後,但如果您需要實際承諾,則應使用exec方法。更多的信息可以在here找到。

在我發現我並沒有明確回答這個問題的更新:

我從來沒有見過這種方法在Javascript過嗎?它究竟做了什麼 ?

那麼它的不是原生JavaScript方法,但是Mongoose API的一部分。

+2

如果我設置了mongoose.Promise = require('bluebird'),我還需要使用.exec()嗎?謝謝。 – wayofthefuture

+4

@wayofthefuture我發現文檔在這個問題上很混亂,但我相信你仍然需要調用'exec'方法。這是他們至少在文檔中所做的。爲了確保你可以用'Model.find()instanceof require('bluebird')'檢查自己。希望這可以幫助。 – danillouz

+1

然後有其他操作的問題,如刪除和insertMany ......在這些情況下,exec()是否必要?刪除將不得不使用某種查詢底下... – wayofthefuture

13

丹尼爾已經很好地回答了這個問題。要闡述的方式來建立和執行查詢,看看下面的使用案例的詳盡列表:

查詢建立

直到thenexec一直在叫貓鼬將不執行查詢。這在構建複雜查詢時非常有用。一些示例可以包括使用populateaggregate函數。通過回調

雖然不喜歡被許多由於其嵌套性質

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

執行,查詢可以通過提供可選的回調執行。

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

然後API作爲承諾/ 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函數

從貓鼬文檔If you need a fully-fledged promise, use the .exec() function.

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

文檔沒有明確提到它,但示例顯示用戶。 save()也返回一個promise。除了exec()和save()之外,模型上的任何其他貓鼬方法都會返回一個promise,還是僅僅是這兩個? – thetrystero

+0

如上所述,您可以在查詢中使用'then'來返回承諾。這和'exec'沒什麼兩樣。我發現這個方便的用例是使用'Promise.all'之類的東西。不知道'exec'返回的promise是否在這樣的環境下工作。 –

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

} 

我建議使用藍鳥與貓鼬承諾,要做到這一點,使用此電話:

const mongoose = require('mongoose'); 
mongoose.Promise = require('bluebird'); 
相關問題