为什么Mongoose's JavaScript在同一行中有返回和回调?

Why does Mongoose's JavaScript have both a return and a callback in the same line?

本文关键字:一行 返回 回调 Mongoose JavaScript 为什么      更新时间:2023-09-26

我正在学习猫鼬和回调。我认为回调是用来代替返回的,所以不是回调就是返回,但不是两者都用。然后我偶然发现了这一点,其中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
});

我用谷歌搜索了一下,发现这个问题有两个答案,都有回调,但一个没有返回,一个有。他们都对吗?如果是这样,我应该在什么时候用回调放一个返回?

不返回:

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

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

下面是一个非常简单的例子:

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中添加一条返回语句:

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

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

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

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

的例子:

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

这是一个有趣的区别。通常,回调被用作返回的替代,但是在技术上,提供一个额外的返回通常没有什么问题——Mongoose可能会忽略返回的数据。

我的猜测是,返回是为了与其他不使用回调的方法保持一致。例如:

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

对此持保留态度——在我对Mongoose代码库的搜索中,我找不到任何包含返回的理由。总之,不管怎样,我还是要用它,因为它不会有伤害,这就是猫鼬的记录。