javascript - 已解决 为什么 MySQL 语句在 Node REPL 中逐行键入时可以正常工作,而在函数中却不行?
问题描述
我正在编写一个 reddit 机器人来扫描所有评论并在每次任何用户使用某个关键字写评论时写入 MySQL 表,因此该表会跟踪任何给定用户使用该关键字的次数。所有这一切都很好。当我使用 NodeJS 制作一个允许您查询数据库的小型网站时,问题就来了。当我启动 Node REPL 会话并一次执行以下几行时,一切正常:
const mysql = require('mysql');
data = [];
let db = mysql.createConnection({ // Log into the database
host: "leHost",
user: "leUserName",
password: "leSuperSecurePassword",
database: "reddit"
});
db.connect(function(err) { // connect to the database via our login
db.query("SELECT * FROM nicecount", function(err, result, fields) { // Execute this statement
data.push(result); // add each row that is returned to data[]
});
});
console.log('returning this data:');
// Data is in the form of [['Username', value], ['Username', value]]
console.log(util.inspect(data));
db.end(); // Close the connection to the database
我得到的东西看起来像这样:
[
RowDataPacket { username: 'benjixinator', value: 3 },
RowDataPacket { username: 'SciNZ', value: 1 },
RowDataPacket { username: 'RetainedByLucifer', value: 1 },
RowDataPacket { username: 'marknielsen777', value: 1 }
]
但是当我把它变成这样的函数时:
const mysql = require('mysql');
function getUserData(username) {
data = [];
let db = mysql.createConnection({ // Log into the database
host: "leHost",
user: "leUserName",
password: "leSuperSecurePassword",
database: "reddit"
});
db.connect(function(err) { // connect to the database via our login
db.query("SELECT * FROM nicecount", function(err, result, fields) { // Execute this statement
data.push(result); // add each row that is returned to data[]
});
});
console.log('returning this data:');
// Data is in the form of [['Username', value], ['Username', value]]
console.log(util.inspect(data));
db.end(); // Close the connection to the database
return data;
}
然后运行它,我得到以下信息:
> response = getUserData('benjixinator');
returning this data:
[]
[]
> response
[ undefined ]
我不知道为什么有两个空括号[]
。我希望输出是这样的:
> response = getUserData('benjixinator');
returning this data:
[
RowDataPacket { username: 'benjixinator', value: 3 },
RowDataPacket { username: 'SciNZ', value: 1 },
RowDataPacket { username: 'RetainedByLucifer', value: 1 },
RowDataPacket { username: 'marknielsen777', value: 1 }
]
> response
[RowDataPacket { username: 'benjixinator', value: 3 }, RowDataPacket { username: 'SciNZ', value: 1 }, etc...]
我的两部分问题:
- 为什么在函数中结果不同?
- 如何修改我的代码以使其在作为函数运行时返回 MySQL 数据?
编辑:解决方案
使用@Shadow 提到的这个问题的答案,如何使用 Node 正确地从 mysql 返回结果?,我能够让它为我工作,如下所示:
问题的要点是数据库查询是异步的,这意味着在我访问数组以检查查询结果时,查询结果并未放入数组中。该怎么办?如果只有针对此类问题的特定 JavaScript 功能...
然后,突然之间,JavaScript ES6 Promises出现了!
function getUserData(username ) {
return new Promise((resolve, reject) => {
db.query('SELECT * FROM nicecount WHERE username = ?', [username], (err, rows) => {
// The addition of the username bit was not part of the solution, it's just part of my project.
if (rows == undefined) {
reject(new Error('Error: rows is undefined.'));
} else {
resolve(rows);
}
});
});
}
所以现在我有一个函数,getUserData
它查询数据库并返回一个承诺。然后,我这样使用这个承诺:
getUserData(req.body.username)
.then(response => {
data = [];
for (let row of response) {
data.push({
username: row.username,
value: row.value
// ^ I am sure there is a more efficient way to do this,
// please @ me in a comment with the answer...
});
}
// Now, data[] has the results from the query,
// and I can do whatever I want with them
// from here to the end of this .then() block.
})
.catch(err => {
console.log('Error: ' + err);
});
这就是它的完成方式!再次感谢@Shadow!
解决方案
推荐阅读
- postgresql - 插入语句,从源表返回列
- ordercloud - Python OrderCloud sdk 扩展属性过滤器不起作用
- c++ - 如何让两个 QGraphicsViews 同时滚动?
- express - 我们如何记录每个 http 请求和响应并将其保存到数据库中
- java - 在 JComboBox 上键入时从数据库中自动过滤 JComboBox 数据
- c# - 如何从文本框中删除某组字符
- excel - 如何使用 vba 创建带有图片比例 url 的图片评论
- nginx - 通过 Jenkins 自动化自己的工作并通过 HTTPD 或 NGINX 在 Kubernetes 上发布
- node.js - SequlizeJS 连接经常超时
- spring - Spring - RESTful 提供不同的实体表示