NodeJS exec函数是做什么的?

fzwojiic  于 2023-01-20  发布在  Node.js
关注(0)|答案(7)|浏览(207)

我遇到了一段Mongoose代码,其中包括一个查询findOne和一个exec()函数。
我从来没有在Javascript中见过这个方法?它到底是做什么的?

z31licg0

z31licg01#

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

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

exec

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

因此,当您不传递回调时,您可以构建查询并最终执行它。
您可以在mongoose docs中找到更多信息。

    • 更新**

在结合Mongoose异步操作使用Promises时需要注意的是,Mongoose查询不是Promises。查询确实返回一个 * thenable *,但是如果你需要一个 * real * Promise,你应该使用exec方法。更多信息可以在here中找到。
在更新过程中,我注意到我没有明确回答这个问题:
我从来没有在Javascript中见过这个方法?它到底是做什么的?
嗯,它不是一个原生JavaScript方法,而是Mongoose API的一部分。

lmvvr0a8

lmvvr0a82#

我从来没有使用exec()函数来完成模型上的CRUD(创建、读取、更新、删除),当我想在模型上使用CRUD时,我这样使用它:

const user = await UserModel.findOne(userCondition);

而且它总是能完成这项工作。所以我想知道“exec()是用来做什么的”?当我在 Mongoose 文档中搜索时,我找到了答案here
是否应该在await中使用exec()?
故事是这样的。
您有两种方法来执行模型上的查询。使用callback或使用exec()函数。“但是”您也可以使用awaitexec()函数返回一个承诺,即您可以将其与then()async/await一起使用来“异步”执行模型上的查询。因此问题是“如果我可以只使用user = await UserModel.find()并且它正确地工作,那么我为什么要使用exec()函数呢?"。您可以在document中找到答案:
使用awaitexec()或不使用exec()之间有两个区别。

  • 从功能的Angular 来看,使用awaitexec()以及不使用exec()没有区别,只是当你调用一个查询而不使用exec()callback时,它返回一个thenable,这有点像promise,但它不是promise。(您可以在这里找到不同之处)。但是当您使用exec()运行查询时,您得到的响应完全是一个承诺。
// 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();
  • 另一个区别是,如果您将awaitexec()一起使用,那么如果您在执行查询时捕获到任何错误,您将获得更好的“堆栈跟踪”。

这两行,做同样的事情:

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

egmofgnx3#

丹尼尔已经很好地回答了这个问题。为了详细说明构建和执行查询的方法,请看下面的用例:

查询构建

Mongoose在thenexec被调用之前不会执行查询。这在构建复杂查询时非常有用。一些示例包括使用populateaggregate函数。

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

通过回调执行

尽管由于其嵌套特性而不受欢迎,但可以通过提供可选回调来执行查询。

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

那么API就是一个承诺/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文件If you need a fully-fledged promise, use the .exec() function.

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

u59ebvdq4#

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

}

我建议对 Mongoose 使用Bluebird promises,要做到这一点,请使用以下调用:

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

ckocjqey5#

所有答案都是正确的,但最简单的方法是使用现代异步等待方法。

async ()=> {
const requiresUser = await User.findByIdAndUpdate(userId,{name:'noname'},{ new:true}).exec()
nkhmeac6

nkhmeac66#

基本上,mongoose查询不返回任何promise,所以如果我们希望查询像promise一样工作,我们就使用exec函数。

nfzehxib

nfzehxib7#

一种获取数据的方式,

find().exec((err,data)=>{

})

other way,

const res=await find()

相关问题