不使用回调时返回未定义的函数,在使用回调时,JS表示未定义函数



请注意,在SO上已经提出了类似的问题,我经历了其中的大部分。

我正在制作一个 RESTful 服务,需要查询数据库才能获取数据。我编写的代码正确查询数据库,但始终返回未定义。代码在这里:

function returnAll(){
ModuleDBService.find({},function(err,data){
if(err){
console.log('Error occured while retrieving the documents!');
}
return data;
});
}

我使用以下方法导出模块:

module.exports = {
getAll:returnAll
};

在挖掘了很多之后,我发现我需要使用回调来获取数据。我浏览了许多示例,并尝试将类似的技术应用于我的代码,修改后的代码如下所示:

function getAllFromDatabase(callback){
ModuleDBService.find({},function(err,data){
if(err){
console.log('Error occured while retrieving the documents!');
}
callback(returnAll(data));
});
}

function returnAll(data){ return data;}

然后以与上述类似的方式返回它。

但是现在我收到错误,ModuleDAO.getAll不是一个函数(我正在使用var ModuleDAO = require('数据库服务的路径')。

我尝试了许多代码变体,浏览了YouTube上的几个视频,所有这些视频都会导致返回未定义,或者返回到上述错误。如果有人可以修复代码并阐明整个回调问题(或者可以提供可靠的文档来理解它),这将是一个很大的帮助。

谢谢。

编辑:在所有非常有用的答案之后,这里有一个摘要:

回调不能返回数据,传递您希望程序使用数据调用的函数(回调函数)。就我而言,是我的路由器返回了数据。

以下是更正后的代码:

function returnAll(callback) {
ModuleDBService.find({}, function (err, data) {
if (err) {
console.log("Error while retrieving the document!")
callback(null);
}
callback(data);
});
}

我在路由器中使用此代码作为:

mainAPIRouter.post('/api/module', function (req, res) {
try {
moduleDAO.getAll(function(data){
res.status(200);
res.json(data);
});
} catch (error) {
res.status(500);
return res.send("Invalid request");
}
});

感谢所有帮助过的人!:)

你很接近。您不需要returnAll()函数,您需要导出getAllFromDatabase并向其传递callback

function getAllFromDatabase(callback){
ModuleDBService.find({},function(err,data){
if(err) {
console.log('Error occured while retrieving the documents!');
}
callback(data);
});
}
module.exports = {
getAllFromDatabase: getAllFromDatabase
};

然后,当你想使用它时,你需要一个回调函数

dataModule.getAllFromDatabase(callbackHandler);
function callbackHandler(dataFromDatabase) {
// this function will be executed when ModuleDBService executes the callback
console.log(dataFromDatabase);
}

一个小细节:如果err是 Truthy,则不应执行回调:

if(err) {
console.log('Error occured while retrieving the documents!');
} else {
callback(data);
}

您希望简单地使用所需的数据作为参数来调用callback()。通过将另一个函数传递到回调中,使事情变得更加复杂。尝试类似操作:

function returnAll(callback) {
ModuleDBService.find({}, function(err, data) {
if (err) return callback(err)
callback(null, data);
});
}
returnAll(function(err, data)) {
// it's customary for callbacks to take an error as their first argument
if (err) {
console.log('Error occured while retrieving the documents!');
} else {
// use data here!!
}
}

如前所述,您可以使用回调。如果您愿意,也可以使用承诺:

function returnAll(){
return new Promise(function(resolve, reject) {
ModuleDBService.find({},function(err,data){
if(err){
console.log('Error occured while retrieving the documents!');
reject(err);
}
resolve(data);
});
});
}

然后,您将使用类似以下内容来访问它:

returnAll()
.then(data=> {console.log(data); })
.catch(err=> { console.log(err); });

*编辑:由于您想使用回调,我想我也会在那里添加我的 0.02 美元。最简化的方法是仅使用ModuleDBService.find传入的回调,而不使用临时函数。但是最好验证回调实际上是一个函数,如果不是让它成为一个函数......使代码更具容错能力。

function returnAll(cb){
if(typeof cb!=='function') cb = function() {};
ModuleDBService.find({},cb);
}

最新更新