为啥 Mongoose 的 JavaScript 在同一行同时有返回和回调?

Posted

技术标签:

【中文标题】为啥 Mongoose 的 JavaScript 在同一行同时有返回和回调?【英文标题】:Why does Mongoose's JavaScript have both a return and a callback in the same line?为什么 Mongoose 的 JavaScript 在同一行同时有返回和回调? 【发布时间】:2016-01-05 12:39:03 【问题描述】:

我正在学习 Mongoose 和回调。我认为回调是用来代替返回的,所以它要么是回调要么是返回,但不是两者兼而有之。然后我偶然发现了这个,returncb 在同一行。

// define a schema
var animalSchema = new Schema( name: String, type: String );

// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function (cb) 
  return this.model('Animal').find( type: this.type , cb);


var Animal = mongoose.model('Animal', animalSchema);
var dog = new Animal( type: 'dog' );

dog.findSimilarTypes(function (err, dogs) 
  console.log(dogs); // woof
);

我在 Google 上四处搜索,发现这个 SO 问题有两个答案,都带有回调,但 one without 是返回,one with。他们都正确吗?如果是这样,我应该什么时候用回调返回?

没有回报:

animalSchema.statics.findByName = function (name, cb) 
    this.find( name: new RegExp(name, 'i') , cb);

返回:

animalSchema.methods.findSimilarTypes = function (cb) 
  return this.model('Animal').find( type: this.type , cb);

【问题讨论】:

【参考方案1】:

这是一个有趣的区别。通常,回调被用作返回的替代品,但存在额外的返回通常在技术上没有任何问题 - Mongoose 可能会忽略返回的数据。

我的猜测是返回是为了与其他不使用回调的方法保持一致。像下面这样:

personSchema.virtual('name.full').get(function () 
  return this.name.first + ' ' + this.name.last;
);

对此持保留态度 - in my search of the Mongoose codebase 我找不到任何理由退货。不过总而言之,我还是会拥有它,因为它不会造成伤害,而 mongoose 就是这样记录它的。

【讨论】:

【参考方案2】:

通常在异步编程技术中,在特定点使用 return 语句和回调是一种很好的做法。例如,当代码有另一个回调时。这可以防止在同一函数中意外执行多个回调。

这是一个非常简单的例子:

var failureCallback = function(err) 
    console.log("Failed");
    // do something with err


var successCallback = function(data) 
    console.log("Success");
    // do something with data        


var asyncFunction = function(failureCallback, successCallback) 
    getDataFromDb(err, data) 
        if(err) 
            failureCallback(err);
        
    successCallback(data);
    

这种情况下如果出现错误,肯定会调用第一个回调,但也有可能同时调用第二个回调。所以控制台输出可能是:

Failed
Success

为防止这种情况,您只需在 failureCallback 中添加一个 return 语句:

var asyncFunction = function(failureCallback, successCallback) 
    getDataFromDb(err, data) 
        if(err) 
            return failureCallback(err);
        
    successCallback(data);
    

因此,并非只能使用 return 或 callback 而不能同时使用两者。事实上,在某些情况下,您必须将它们一起使用。

所有这些都是说,在您的 Mongoose 示例的情况下,这可能是函数的要求(尽管看起来并非如此),但它也可能是习惯的力量原作者使用 return 和回调。根据上下文,两者都是正确的。在这些用例中,使用 return 可能是必要或不必要的预防措施。

【讨论】:

是否说将 return 与回调一起放置永远不会有坏处?【参考方案3】:

在同一行上使用返回和回调,您“强制”程序从您的函数返回。如果你只是使用回调,之后的代码有时仍然会被执行。

例子:

someAsyncFunction(err, data)  
    if(err) 
       return callback(err)
      
     /* do some code with your data */ 
     callback()

【讨论】:

很好的答案,大师!

以上是关于为啥 Mongoose 的 JavaScript 在同一行同时有返回和回调?的主要内容,如果未能解决你的问题,请参考以下文章

为啥循环通过 Mongoose 对象会显示元数据?

当我“更新”时,Mongoose 操作字段是“查找”,为啥?

Mongoose 为啥要添加空白数组?

为啥 Mongoose 不验证空文档?

为啥 Mongoose 不验证空文档?

为啥 Mongoose 不允许我访问 JSON 属性?