关于Nodejs 回调函数问题
关于Nodejs 回调函数问题
- var setUser = function () {
-
function callback() {
-
sql.open(conn_str, function (err, conn) {
-
if (err) {
-
console.log("Error opening the connection!");
-
return;
-
}
-
conn.queryRaw("SELECT Username,Password FROM Users", function (err, results) {
-
if (err) {
-
console.log("Error running query!");
-
return;
-
}
-
for (var i = 0; i < results.rows.length; i++) {
-
console.log(results.rows[i][0].toString());
-
}
-
return results.rows[1][0].toString();
-
});
-
});
-
}
-
return callback();
- }
- exports.setUser = setUser;
- var users = require(’./dbCon.js’);
- console.log(users.setUser());
// node index.js the result: return is unfined console.log is ok. 能看懂不。。。求教
代码格式化挺重要的,咋就这么不钻业捏~眼睛不好,花呀~编辑框已经提供了常见的样式~
关于Nodejs 回调函数问题
在你的代码中,你尝试通过同步的方式调用一个异步操作(数据库查询)。由于JavaScript的事件循环机制,这种方式会导致无法得到预期的结果。下面我将详细解释这个问题,并提供正确的解决方案。
问题分析
在dbCon.js
文件中的setUser
函数,你定义了一个回调函数callback
,并在其中执行了数据库查询。然而,在index.js
中,你直接调用了users.setUser()
,期望它返回查询结果。这实际上是一个常见的误解,因为在Node.js中,异步操作(如数据库查询)不能直接通过同步方式获取结果。
解决方案
在处理异步操作时,你需要使用回调函数来处理结果。以下是修改后的代码:
dbCon.js
var sql = require('mssql'); // 假设你使用的是mssql库
var conn_str = 'your_connection_string_here'; // 数据库连接字符串
var setUser = function(callback) {
sql.open(conn_str, function(err, conn) {
if (err) {
console.log("Error opening the connection!");
return callback(err);
}
conn.queryRaw("SELECT Username, Password FROM Users", function(err, results) {
if (err) {
console.log("Error running query!");
return callback(err);
}
var usernames = [];
for (var i = 0; i < results.rows.length; i++) {
usernames.push(results.rows[i][0].toString());
}
callback(null, usernames);
});
});
};
module.exports = {
setUser: setUser
};
index.js
var dbCon = require('./dbCon.js');
dbCon.setUser(function(err, usernames) {
if (err) {
console.error("An error occurred:", err);
return;
}
console.log("Usernames:", usernames);
});
解释
- 回调函数传递:在
dbCon.js
中,setUser
函数接受一个回调函数作为参数。当数据库查询完成时,该回调函数会被调用。 - 错误处理:如果在任何步骤发生错误,我们立即调用回调函数并传入错误对象。
- 结果传递:成功执行查询后,我们将结果数组传递给回调函数。
这样,你就可以正确地处理异步操作的结果,而不会遇到undefined
的问题。
疑问在哪?
他使用了高阶函数,首先外面少了一层函数调用;其次,return的数据到不了外层调用,undefined…闭包、异步及回调原理不太清晰吧^ ^
[@DevinXian](/user/DevinXian) 我也是要测试ajaxIm的demo 才搞一下这个。麻烦求教一下。
for (var i = 0; i < results.rows.length; i++) { console.log(results.rows[i][0].toString()); }
这有结果吗?
我把你的代码稍微改改,NodeJS菜鸟风格- -正好今天写完年终总结,有点时间~~ 首先是db.js:
var setUser = function (callback) {//callback回调,数据库访问是异步操作,直接return会悲剧
sql.open(conn_str, function (err, conn) {
if (err) {
console.log("Error opening the connection!");
return callback(err);
}
conn.queryRaw("SELECT Username,Password FROM Users", function (err, results) {
if (err) {
console.log("Error running query!");
return callback(err);
}
for (var i = 0; i < results.rows.length; i++) {
console.log(results.rows[i][0].toString());
}
//return results.rows[1][0].toString();//这里return的是内层函数
callback(err, results);//使用回调获取数据,第一个参数表示异常
});
});
};
exports.setUser = setUser;
index.js:
var User = require('./db.js');
User.setUser(function(err, data){
//handle err...
//handle data
});//此处传入一个函数作为回调获取结果
[@hades](/user/hades) 有的。(忙在群里 没及时刷新)楼下的兄弟帮我解决了。thanku all the same
[@DevinXian](/user/DevinXian) 谢谢。。我只想说 你们这年总结太及时了。虽然我没看懂。我研究研究 。。best wishes。
谢谢大家!
[@cnhonker07](/user/cnhonker07) 之前说少了一层调用说错了,代码中return callback()本身就调用了,我没看仔细,sorry,所以[@hades](/user/hades) 打印肯定会有的~
[@DevinXian](/user/DevinXian) @.@其实我只是想说,他的回调没写,就你写的那句。
[@hades](/user/hades) 大哥啊。。你去看看我刚提问的一个问题。。跟这个不是差别很多。。。
从你的描述来看,问题在于你试图在 index.js
中直接调用一个需要异步操作的函数 setUser
,这会导致未定义的结果。这是因为 setUser
函数中的数据库查询是异步执行的,而你在调用它时没有处理这种异步性。
解决方案
你可以通过传递回调函数来处理异步操作的结果。以下是修改后的代码示例:
dbCon.js
var setUser = function(callback) {
sql.open(conn_str, function(err, conn) {
if (err) {
console.log("Error opening the connection!");
return callback(null);
}
conn.queryRaw("SELECT Username,Password FROM Users", function(err, results) {
if (err) {
console.log("Error running query!");
return callback(null);
}
var usernames = [];
for (var i = 0; i < results.rows.length; i++) {
usernames.push(results.rows[i][0].toString());
}
// 返回结果给回调函数
callback(usernames);
});
});
};
module.exports = {
setUser: setUser
};
index.js
var dbCon = require('./dbCon.js');
dbCon.setUser(function(usernames) {
console.log("Usernames:", usernames);
});
解释
- 回调函数:在
dbCon.js
中,setUser
函数接受一个回调函数作为参数。当数据库查询完成后,这个回调函数会被调用,并传递查询结果。 - 异步处理:在
index.js
中,我们通过传递一个回调函数来处理setUser
的异步结果。这样可以确保在数据准备好后才进行输出。
通过这种方式,你可以正确地处理异步操作的结果,避免出现 undefined
的情况。