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

时间:2018-04-18 20:45:33

标签: javascript node.js callback

考虑到在SO上提出了类似的问题,我经历了大部分问题。

我正在制作RESTful服务,需要查询数据库以获取数据。我编写了正确查询数据库的代码,但确实一直返回undefined。代码在这里:

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上观看了几个视频,所有这些视频都导致返回undefined,或者返回上述错误。如果任何人都可以修复代码并对整个回调事件进行说明(或者可以提供可靠的文档来理解它),那将是一个很好的帮助。

感谢。

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

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

以下是更正后的代码:

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

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

3 个答案:

答案 0 :(得分:1)

你很亲密。您不需要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);
}

答案 1 :(得分:1)

您只想使用您需要的数据作为参数调用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!!
  }
}




答案 2 :(得分:1)

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

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。最简化的方法是在没有ad-hoc功能的情况下使用您使用ModuleDBService.find传入的回调。但验证回调实际上是一个函数是好的,如果不是一个函数......使代码更容错。

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