我无法从node.js中的自定义模块接收数据

时间:2013-05-18 20:39:09

标签: node.js module callback

我写了一个名为accountManager.js的模块

var sqlite3 = require('sqlite3');

var db = new sqlite3.Database("./users.db");

exports.userExists = function userExists(nickName) {
    var stmt = 'SELECT * FROM users WHERE login="' + nickName + '"';
    db.each(stmt,function(err,row) {
        if(row) {
            if(row.login==nickName) return true;
            else return false;
        }
    });
}

在我的主app.js文件中,我有

var accountManager = require('./lib/accountManager');
console.log(accountManager.userExists('user1'));

此应用程序在控制台中显示“未定义”...我检查该模块工作正常,我猜这是回调问题?请给我一些帮助,我不明白这段代码有什么问题...

2 个答案:

答案 0 :(得分:2)

您需要了解异步函数和回调如何工作。

基本上你不能在回调中返回任何内容,但需要调用你传递给userExists的另一个回调。

var sqlite3 = require('sqlite3');
var db = new sqlite3.Database("./users.db");

exports.userExists = function userExists(nickName, cb) {
    var stmt = 'SELECT * FROM users WHERE login="' + nickName + '"';
    db.each(stmt,function(err,row) {
        if(row) {
            cb(row.login == nickName);
        }
    });
}

使用它:

accountManager.userExists('user1', function(found) {
    console.log(found);
});

除此之外,您的代码有一个空洞的SQL注入漏洞,可能无法执行您想要执行的操作。这是userExists函数的固定版本:

exports.userExists = function userExists(nickName, cb) {
    var stmt = 'SELECT COUNT(*) AS cnt FROM users WHERE login = ?';
    db.get(stmt, nickName, function(err, row) {
        cb(row.cnt > 0);
    });
};

为什么这样更好?

  1. 您不会在SQL字符串中插入值(这很糟糕,您必须转义以避免SQL注入)。单独传递更清洁,更好
  2. 您只想知道用户是否存在。所以检索计数(这将是一行)。如果用户不存在则为零。
  3. 现在始终调用回调。在第一个更接近您的代码的示例中,只有在找到用户时才会调用它 - 很可能不是您想要的。

答案 1 :(得分:0)

您正在从db.each的回调中返回一个值。但是,外部函数(userExists)返回的值 not ,它可能会在调用传递给db.each的函数之前返回。

您可能希望向userExists函数提供回调,如下所示:

exports.userExists = function (nickName, cb) {
    var stmt = 'SELECT * FROM users WHERE login="' + nickName + '"';
    var found=false;
    db.each(stmt,function(err,row) {
        if(row) {
            if(row.login==nickName) {
                found=true;
                cb(true);
            }
        }
    }, function () {
        if (!found) {
            cb(false);
        }
    });
}

然后,将其称为:

 var accountManager = require('./lib/accountManager');
 accountManager.userExists('user1', function (found) {
     console.log(found);
 });