我无法从node.js中的自定义模块接收数据
我写了一个名为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'));
这个应用程序在控制台中显示'undefined'…我检查模块工作正常,我想这是callback问题? 请给我一些帮助,我不明白这个代码有什么问题…
您需要了解asynchronous函数和callback如何工作。
基本上你不能在callback中返回任何东西,但需要调用另一个你传递给userExists
callback。
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); }); };
为什么这更好?
- 你不要插入SQLstring中的值(这是不好的,你将不得不逃避东西,以避免SQL注入)。 分开传递更清洁,更好
- 你只是想知道用户是否存在。 所以检索计数(这将是一行)。 如果不是零用户存在。
- 现在callback总是被调用。 在第一个更接近你的代码的例子中,只有在用户被发现的情况下才会调用 – 很可能不是你想要的。
你从db.each
的callback中返回一个值。 但是,这个值不是由外部函数( userExists
)返回的,可能在传递给db.each
的函数被调用之前返回。
你可能想要给userExists
函数提供一个callback,就像这样:
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); });