我发现了一段包含查询findOne和exec()函数的Mongoose代码。
我以前从没在JavaScript中见过这种方法?它到底是做什么用的?
我发现了一段包含查询findOne和exec()函数的Mongoose代码。
我以前从没在JavaScript中见过这种方法?它到底是做什么用的?
callback
或exec
方法执行。
callback
:User.findOne({ name: 'daniel' }, function (err, user) {
//
});
exec
:
User
.findOne({ name: 'daniel' })
.exec(function (err, user) {
//
});
exec
方法。更多信息可以在这里找到。嗯,这不是JavaScript的本地方法,而是Mongoose API的一部分。我以前从未见过JavaScript中的那种方法?它到底是做什么的?
我从来不使用exec()
函数对模型进行CRUD(Create, Read, Update, Delete)操作。当我需要对模型进行CRUD操作时,我会这样使用:
const user = await UserModel.findOne(userCondition);
它总是能完成任务。所以我想知道"exec()
用于什么?"。
在mongoose文档中搜索,我发现答案在这里。
你应该使用
await exec()
吗?
以下是故事的背景。
您有两种方法可以对模型执行查询:使用回调或使用exec()
函数。但也可以使用await
。 exec()
函数返回一个promise,您可以将其与then()
或async/await
一起使用来在模型上“异步”执行查询。那么问题是:"如果我只想使用user = await UserModel.find()
并且它能够正常工作,那么为什么要使用exec()
函数呢?"。在文档中可以找到答案:
使用await
和exec()
与不使用它们相比,有两个不同之处。
await
和exec()
与不使用它们没有区别。只是当您调用没有exec()
或callback
的查询时,它返回一个thenable,类似于promise但不是promise。(您可以在这里找到区别)。但当您使用exec()
运行查询时,会准确地得到一个promise作为响应。// returns a thenable as response that is not a promise, but you can use await and then() with it.
const user = await UserModel.findOne(userCondition);
// returns exactly a promise.
const user = await UserModel.findOne(userCondition).exec();
exec()
中使用await
,当你捕获任何执行查询中的错误时,你将获得更好的“堆栈跟踪”。 所以:const user = await UserModel.findOne(userCondition);
// does exactly as the before line does, but you get a better stack trace if any error happened
const user = await UserModel.findOne(userCondition).exec();
Daniel已经很好地回答了这个问题。为了详细阐述构建和执行查询的详尽方法列表,请看以下用例:
查询构建
在Mongoose中,只有在调用then
或exec
之后,才会执行查询。当构建复杂的查询时,这非常有用。一些示例包括使用populate
和aggregate
函数。
User.find({name: 'John'}) // Will not execute
通过回调函数执行
虽然由于其嵌套的特性而被许多人所不喜欢,但查询可以通过提供可选的回调函数来执行。
User.find({name: 'John'}, (err, res) => {}) // Will execute
将API转换为Promises/A+风格
Mongoose查询确实提供了then
函数,但它与常规的promises不同。简单来说,Promises/A+规范要求then
函数的工作方式与我们通常使用的promises相似。
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 文档 如果您需要完整的承诺,请使用 .exec() 函数。
User.find({name: 'John'}).exec(); // Will execute returning a promise
then
来返回一个Promise。这与exec
并没有太大的区别。我发现这个用例很方便,特别是在使用类似于Promise.all
的东西时。不确定exec
返回的Promise是否适用于这种情况。 - Anshuul KaiPromise.all
的例子可能过于简单了,你应该使用 find(name: { $in: ['John', 'Bob'] })
。 - OneCricketeerexec()
如果没有提供回调函数,将返回一个promise。因此,以下模式非常方便和通用 - 它可以很好地处理回调或promise:
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);
}
我建议在Mongoose中使用Bluebird Promise,要这样做,请使用以下调用:
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
所有的答案都是正确的,但最简单的方法是使用现代的 async/await 方法。
async ()=> {
const requiresUser = await User.findByIdAndUpdate(userId,{name:'noname'},{ new:true}).exec()
获取数据的一种方法:
find().exec((err,data)=>{
})
其他方法:
const res=await find()
基本上,mongoose查询不会返回任何承诺。因此,如果我们希望它们像承诺一样工作,我们使用exec函数。
const result = await Model.findOne({filter:filter}).exec();
return result ;
**or**
const x = await Model.findOne({filter:filter}).exec()
.then((data)=>{
return (data);
}).catch((err)=> {
return (err);
});
exec
方法。至少在文档中是这样做的。为了确定,你可以使用Model.find() instanceof require('bluebird')
进行自查。希望能有所帮助。 - danillouzModel.update().exec()
来确保它会执行。然后你可以在不等待更新的情况下响应API。这可能会帮助到某些人。 - Yogeshconst query = await Model.find({});
然后稍后执行query.exec();
? - Matthew Wolman