2015-10-08 20 views
1

我正在学习猫鼬和回调。我认为使用回调代替回报,因此它是回调或回报,但不是两者。然后我偶然发现,returncb在同一行。为什么Mongoose的JavaScript在同一行中有回调和回调?

// 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了一圈,发现这太问题既具有回调的两个答案,但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); 
} 

回答

4

通常在异步编程技术中,在特定点处使用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 

为了防止这种情况,只需添加一个return语句到failureCallback:

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

因此,不是说你只能使用回报或回调的情况下但不是两个。事实上,在某些情况下,你必须一起使用它们。

所有这一切都可以这么说,在你的Mongoose例子中,它可能是函数的一个要求(虽然看起来不是这样),但它也可能是一种习惯的力量原作者使用返回与回调一起。根据具体情况,两者都是正确的。在这些用例中使用return可能是必要或不必要的预防措施。

+0

难道说,它从未伤害投入与回报的回调相处? – Melissa

+1

是的,这是正确的。 – ryder

0

这是一个有趣的差异。通常,回调函数被用作返回值的替代品,但通常不存在额外的返回值在技术上的错误 - Mongoose可能会忽略返回的数据。

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

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

用一粒盐借此 - in my search of the Mongoose codebase我找不到任何理由包括回报。总而言之,无论如何,我会拥有它,因为它不会受到伤害,这就是猫鼬如何记录它。

3

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

例子:

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

很好的答案,高手! – Miha2255