在猫鼬 Model.find() 和 Model.find().exec() 产生相同的结果。那么为什么还要使用 Model.find().exec() 呢?
In Mongoose Model.find() and Model.find().exec() produce the same result. So why bother using Model.find().exec()?
我注意到 Model.find()
似乎产生了与 Model.find().exec()
相同的结果。两者似乎都检索到适当的 record/document,如以下两段代码所示:
//without exec
export const getUser = async (req, res, next) => {
try{
let mongoDocument = await User.find({name: "OrphanAnnie"})
res.status(200).json(mongoDocument);
} catch (err) {
console.log(err)
}
}
//with exec
export const getUser = async (req, res, next) => {
try{
let mongoDocument = await User.find({name: "OrphanAnnie"}).exec()
res.status(200).json(mongoDocument);
} catch (err) {
console.log(err)
}
}
推荐的方法是什么?在 中,post 建议使用 exec()
可以在不使用回调语法的情况下构建 Mongoose 查询。但是既然查询似乎在不使用 exec()
的情况下工作,为什么还要使用它呢?
Mongoose在promises,
中解释了两者的区别
There are two alternatives for using await
with queries:
await Band.find();
await Band.find().exec();
As far as functionality is concerned, these two are equivalent. However, we recommend using .exec()
because that gives you better stack traces.
以例:
const doc = await Band.find({ name: "Guns N' Roses" }); // works
const badId = 'this is not a valid id';
try {
await Band.find({ _id: badId });
} catch (err) {
// Without `exec()`, the stack trace does **not** include the
// calling code. Below is the stack trace:
//
// CastError: Cast to ObjectId failed for value "this is not a valid id" at path "_id" for model "band-promises"
// at new CastError (/app/node_modules/mongoose/lib/error/cast.js:29:11)
// at model.Query.exec (/app/node_modules/mongoose/lib/query.js:4331:21)
// at model.Query.Query.then (/app/node_modules/mongoose/lib/query.js:4423:15)
// at process._tickCallback (internal/process/next_tick.js:68:7)
err.stack;
}
try {
await Band.find({ _id: badId }).exec();
} catch (err) {
// With `exec()`, the stack trace includes where in your code you
// called `exec()`. Below is the stack trace:
//
// CastError: Cast to ObjectId failed for value "this is not a valid id" at path "_id" for model "band-promises"
// at new CastError (/app/node_modules/mongoose/lib/error/cast.js:29:11)
// at model.Query.exec (/app/node_modules/mongoose/lib/query.js:4331:21)
// at Context.<anonymous> (/app/test/index.test.js:138:42)
// at process._tickCallback (internal/process/next_tick.js:68:7)
err.stack;
}
其他还有:Queries are not promises:
Mongoose queries are not promises. They have a .then()
function for co and async/await
as a convenience. If you need a fully-fledged promise, use the .exec()
function.
const query = Band.find({name: "Guns N' Roses"});
assert.ok(!(query instanceof Promise));
// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (docs) {
// use docs
});
// `.exec()` gives you a fully-fledged promise
const promise = query.exec();
assert.ok(promise instanceof Promise);
promise.then(function (docs) {
// use docs
});
我注意到 Model.find()
似乎产生了与 Model.find().exec()
相同的结果。两者似乎都检索到适当的 record/document,如以下两段代码所示:
//without exec
export const getUser = async (req, res, next) => {
try{
let mongoDocument = await User.find({name: "OrphanAnnie"})
res.status(200).json(mongoDocument);
} catch (err) {
console.log(err)
}
}
//with exec
export const getUser = async (req, res, next) => {
try{
let mongoDocument = await User.find({name: "OrphanAnnie"}).exec()
res.status(200).json(mongoDocument);
} catch (err) {
console.log(err)
}
}
推荐的方法是什么?在 exec()
可以在不使用回调语法的情况下构建 Mongoose 查询。但是既然查询似乎在不使用 exec()
的情况下工作,为什么还要使用它呢?
Mongoose在promises,
中解释了两者的区别There are two alternatives for using
await
with queries:
await Band.find();
await Band.find().exec();
As far as functionality is concerned, these two are equivalent. However, we recommend using
.exec()
because that gives you better stack traces.
以例:
const doc = await Band.find({ name: "Guns N' Roses" }); // works
const badId = 'this is not a valid id';
try {
await Band.find({ _id: badId });
} catch (err) {
// Without `exec()`, the stack trace does **not** include the
// calling code. Below is the stack trace:
//
// CastError: Cast to ObjectId failed for value "this is not a valid id" at path "_id" for model "band-promises"
// at new CastError (/app/node_modules/mongoose/lib/error/cast.js:29:11)
// at model.Query.exec (/app/node_modules/mongoose/lib/query.js:4331:21)
// at model.Query.Query.then (/app/node_modules/mongoose/lib/query.js:4423:15)
// at process._tickCallback (internal/process/next_tick.js:68:7)
err.stack;
}
try {
await Band.find({ _id: badId }).exec();
} catch (err) {
// With `exec()`, the stack trace includes where in your code you
// called `exec()`. Below is the stack trace:
//
// CastError: Cast to ObjectId failed for value "this is not a valid id" at path "_id" for model "band-promises"
// at new CastError (/app/node_modules/mongoose/lib/error/cast.js:29:11)
// at model.Query.exec (/app/node_modules/mongoose/lib/query.js:4331:21)
// at Context.<anonymous> (/app/test/index.test.js:138:42)
// at process._tickCallback (internal/process/next_tick.js:68:7)
err.stack;
}
其他还有:Queries are not promises:
Mongoose queries are not promises. They have a
.then()
function for co andasync/await
as a convenience. If you need a fully-fledged promise, use the.exec()
function.
const query = Band.find({name: "Guns N' Roses"});
assert.ok(!(query instanceof Promise));
// A query is not a fully-fledged promise, but it does have a `.then()`.
query.then(function (docs) {
// use docs
});
// `.exec()` gives you a fully-fledged promise
const promise = query.exec();
assert.ok(promise instanceof Promise);
promise.then(function (docs) {
// use docs
});