猫鼬-exec函数有什么作用?


100

我遇到了一段Mongoose代码,其中包括查询findOne和一个exec()函数。

我以前从未在Javascript中看到过该方法吗?它到底是做什么的?

Answers:


144

基本上,当使用猫鼬时,可以使用助手来检索文档。每个接受查询条件的模型方法都可以通过callbackexec方法执行。

callback

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

exec

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

因此,当您不传递回调时,可以构建查询并最终执行它。

您可以在猫鼬文档中找到其他信息。

更新

Promises与Mongoose异步操作结合使用时,需要注意的一点是Mongoose查询不是 Promises。查询的确返回一个thenable,但是如果您需要一个真正的 Promise,则应使用该exec方法。在这里可以找到更多信息。

在更新期间,我注意到我没有明确回答以下问题:

我以前从未在Javascript中看到过该方法吗?它到底是做什么的?

嗯,这不是本机JavaScript方法,而是Mongoose API的一部分。


4
如果我设置了mongoose.Promise = require('bluebird'),我仍然需要使用.exec()怎么办?谢谢。
wayofthefuture

4
@wayofthefuture我发现文档对此事确实感到困惑,但是我相信您仍然需要调用该exec方法。至少这是他们在文档中所做的。确保可以使用进行检查Model.find() instanceof require('bluebird')。希望这可以帮助。
danillouz

1
然后还有其他操作的问题,例如delete和insertMany ...在这种情况下是否需要exec()?删除将不得不在
幕后

1
如果没有通过回调,exec还会返回一个promise,这非常方便,我必须说
Alexander Mills

它可能会救人。如果您认为Model.update()可以完成其工作,而不必等待一些不太重要的数据被更新并将响应返回给API;您的更新将不会执行。您需要Model.update().exec()确保它将执行。然后,您可以响应api而无需等待更新。
Yogesh

48

丹尼尔回答得很漂亮。要详细说明构建和执行查询的方法,请查看以下用例:

查询大厦

猫鼬将不会执行查询,直到查询then或被exec调用。这在构建复杂查询时非常有用。一些示例可以包括使用populateaggregate函数。

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

通过回调执行

尽管由于其嵌套性质而被许多人所不喜欢,但可以通过提供可选的回调来执行查询。

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

然后将API作为Promises / 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

1
文档没有明确提及它,但示例显示User.save()也返回了Promise。除了exec()和save()之外,模型上的其他猫鼬方法是否还会返回Promise,或者仅仅是这两个?
thetrystero

如上所述,您也可以then在查询中使用以返回承诺。这与没什么不同exec。我发现使用方便的用例是使用Promise.allexec虽然不确定在这种情况下返回的承诺是否有效。
Anshul Koka'4-4-5

[接受解答]
科迪

您能否使用.exec()添加完整的示例?@AnshulKoka是.exec()自动使查询异步还是应该添加异步/等待
O'Dane Brissett

使查询异步将需要async / await,因此我不确定是否理解该问题。只需在我的示例前面加上前缀,即可提出完整示例。
Anshul Koka,

7

exec()如果没有提供回调,将返回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);

}

我建议将Bluebird Promise与Mongoose一起使用,使用此调用:

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

为什么我们需要蓝鸟?当我们有exec()
Indraraj26
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.