在猫鼬 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
});