前言:页面有一个表格上的数据是通过node连接mysql数据库提供接口给前端渲染出来。当用户在表格中对数据进行编辑并点击确定按钮后,前端发送post请求把修改的数据发送给后端,后端将数据库的数据进行更新并查询数据库中所有数据返回给前端渲染。在此分享记录一下自己遇到的问题和解决方案。
实现过程中出现的问题:点击确定按钮后,无法实时更新,要手动刷新页面才能得到新数据。
post部分代码如下:
router.post('/updateInfo',(req,res)=>{
console.log(req.body);
// 定义待执行的SQL语句
const sqlStr='update studentlist set ? where id=?';
// 执行SQL语句
db.query(sqlStr,[req.body,req.body.id],(err,results)=>{
// 执行SQL语句失败
if(err) return console.log(err.message);
// 成功
// 如果results.affectedRows为1 表示成功
if(results.affectedRows===1){
console.log('更新成功');
}
})
// 定义SQL语句,查询要渲染的数据
const sqlStr2='select * from studentlist'
db.query(sqlStr2,(err2,results2)=>{
// 执行SQL语句失败
if(err2)
return res.send({status:1,message:err.message})
console.log(results2);
// 执行SQL语句成功返回结果
res.send({
status:0,
message:'修改成功!',
data:results2
})
})
})
服务器端运行结果:
首先,第一个想法是:难道没有执行更新语句(update)?但是测试发现,数据是已经更新了的(数据库中已经更新),但是输出的查询数据确实更新前的数据(服务器端输出)。排除第一个想法。
第二个想法是:为什么是先查询后更新,明明我写的是先更新后查询?这让我想到了js的异步。难道查询比更新更快,所以查询即便是在后面也是先执行?的确按速度来讲,查询应该更快一些。
那怎么解决这个问题呢?
我首先想到了定时器,于是我将代码改成了:
router.post('/updateInfo',(req,res)=>{
console.log(req.body);
// 定义待执行的SQL语句
const sqlStr='update studentlist set ? where id=?';
// 执行SQL语句
db.query(sqlStr,[req.body,req.body.id],(err,results)=>{
// 执行SQL语句失败
if(err) return console.log(err.message);
// 成功
// 如果results.affectedRows为1 表示成功
if(results.affectedRows===1){
console.log('更新成功');
}
})
// 定义SQL语句,查询要渲染的数据
const sqlStr2='select * from studentlist'
setTimeout(db.query(sqlStr2,(err2,results2)=>{
// 执行SQL语句失败
if(err2)
return res.send({status:1,message:err.message})
console.log(results2);
// 执行SQL语句成功返回结果
res.send({
status:0,
message:'修改成功!',
data:results2
})
}),3000)
})
出现了这样的错误:TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received <ref *1> Query ...和 Cannot set headers after they are sent to the client...
找了半天也没找到哪错了,希望有知道的大佬可以指点一下。
于是我以为难道node中执行sql语句不能用定时器?(瞎猜,没有找到答案)。
然后多番修改,我将代码改成了如下:
router.post('/updateInfo',(req,res)=>{
console.log(req.body);
// 定义待执行的SQL语句
const sqlStr='update studentlist set ? where id=?';
// 执行SQL语句
db.query(sqlStr,[req.body,req.body.id],(err,results)=>{
// 执行SQL语句失败
if(err) return console.log(err.message);
// 成功
// 如果results.affectedRows为1 表示成功
if(results.affectedRows===1){
console.log('更新成功');
}
// 定义SQL语句,查询要渲染的数据
const sqlStr2='select * from studentlist'
db.query(sqlStr2,(err2,results2)=>{
// 执行SQL语句失败
if(err2)
return res.send({status:1,message:err.message})
console.log(results2);
// 执行SQL语句成功返回结果
res.send({
status:0,
message:'修改成功!',
data:results2
})
})
})
})
和上面不一样在于:把查询操作操作嵌入更新操作的db.query()函数中。
这样可以实现实时更新了。
结语:花了挺多时间查如何让查询语句延迟执行,没想到内嵌到更新操作中就可以解决。同时也很好奇db.query()能不能用定时器这个问题(是我知识浅薄了,找不到答案),希望有大佬可以解答我的疑虑。