我无法从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中返回任何东西,但需要调用另一个你传递给userExistscallback。

 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. 你不要插入SQLstring中的值(这是不好的,你将不得不逃避东西,以避免SQL注入)。 分开传递更清洁,更好
  2. 你只是想知道用户是否存在。 所以检索计数(这将是一行)。 如果不是零用户存在。
  3. 现在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); });