Nodejs 巢状函数的匿名函数的回传问题
Nodejs 巢状函数的匿名函数的回传问题
前辈们午安,
小弟尝试在连结 MySQL 时遇到了一些小问题。
问题如下:
我想要将 dbclient.query 的结果回传给呼叫 GetUsers() 的程式码,
但因为 dbclient.query 的 rows 仅存在于匿名函数(lambda)之中。
GetUsers = function () {
dbclient.query("SELECT * FROM user", function (err, rows) {
for (var i = 0 ; i < rows.length ; i++)
console.log(rows[i].uid + " " + rows[i].email);
});
}
GetUsers();
如今我想要将 SQL query 的结果给挪到外部使用,
但我不大想使用全域变数(global)暴力解决,
请问前辈们有什么建议吗?
GetUsers = function () {
dbclient.query("SELECT * FROM user", function (err, rows) {
return rows;
});
}
rows = GetUsers();
当然可以!让我们通过示例代码来解释如何处理这个问题。在 Node.js 中,由于异步编程的特性,我们不能直接从回调函数中返回数据。我们需要使用回调函数或 Promise 来处理这种情况。
示例代码
首先,我们可以通过回调函数来处理 dbclient.query
的结果:
const dbclient = require('./dbclient'); // 假设你有一个数据库客户端
// 定义一个函数,接受一个回调函数作为参数
GetUsers = function (callback) {
dbclient.query("SELECT * FROM user", function (err, rows) {
if (err) {
return callback(err); // 如果有错误,传递错误
}
callback(null, rows); // 没有错误时,传递查询结果
});
};
// 调用 GetUsers 函数,并传入一个回调函数来处理结果
GetUsers(function (err, rows) {
if (err) {
console.error("Error:", err);
return;
}
for (var i = 0; i < rows.length; i++) {
console.log(rows[i].uid + " " + rows[i].email);
}
});
// 你可以在这里继续你的逻辑
使用 Promise
如果你更喜欢使用 Promise,可以这样写:
const dbclient = require('./dbclient');
// 定义一个返回 Promise 的函数
GetUsers = function () {
return new Promise((resolve, reject) => {
dbclient.query("SELECT * FROM user", function (err, rows) {
if (err) {
return reject(err); // 如果有错误,拒绝 Promise
}
resolve(rows); // 没有错误时,解析 Promise
});
});
};
// 调用 GetUsers 函数,并使用 .then 和 .catch 来处理结果
GetUsers()
.then(rows => {
for (var i = 0; i < rows.length; i++) {
console.log(rows[i].uid + " " + rows[i].email);
}
})
.catch(err => {
console.error("Error:", err);
});
// 你也可以在这里继续你的逻辑
解释
-
回调函数:在第一个示例中,我们定义了一个接受回调函数的
GetUsers
函数。当查询完成时,我们将结果传递给回调函数。这种方式是 Node.js 中处理异步操作的一种常见方法。 -
Promise:在第二个示例中,我们使用了 Promise。这使得代码更加简洁,并且可以更容易地进行链式调用。Promise 使异步代码看起来更像同步代码,提高了可读性和可维护性。
这两种方法都可以有效地处理异步查询的结果,避免了全局变量的使用。希望这些示例能帮助你解决问题!
GetUsers = function (callback) {
dbclient.query("SELECT * FROM user", function (err, rows) {
callback(rows);
});
}
GetUsers(function (rows) {
// here is your rows.
});
在这个例子中,dbclient.query
是一个异步操作,因此直接返回 rows
并不能达到预期的效果。你需要使用回调函数来处理异步操作的结果。
以下是一个改进后的示例:
GetUsers = function (callback) {
dbclient.query("SELECT * FROM user", function (err, rows) {
if (err) {
callback(err, null);
return;
}
for (var i = 0; i < rows.length; i++) {
console.log(rows[i].uid + " " + rows[i].email);
}
callback(null, rows);
});
};
// 调用 GetUsers 函数并传递回调函数
GetUsers(function (err, result) {
if (err) {
console.error("Error fetching users:", err);
return;
}
// 在这里处理查询结果
console.log("Users fetched successfully:", result);
});
解释:
- 回调函数:我们将
GetUsers
函数修改为接受一个回调函数作为参数。这样可以在dbclient.query
操作完成后执行回调函数,并将查询结果传递回去。 - 错误处理:在回调函数中处理可能出现的错误。
- 外部处理:在调用
GetUsers
时,传递一个回调函数来处理查询结果。
这种方法避免了使用全局变量,并且能更好地处理异步操作的结果。