Async/Await异步问题:Express POST请求后无法获取更新的MySQL数据
问题分析与修复方案
核心问题拆解
- 全局
usersPromise仅在服务器启动时执行一次数据库查询,之后不会重新拉取数据,所以新用户添加后页面无法显示,只有重启服务器才会重新执行这个Promise。 refresh函数内部定义的是局部users变量,和全局的users没有任何关联,而且函数没有返回值,调用后完全起不到更新数据的作用。- POST请求处理中重复注册
app.get("/")路由,会导致路由逻辑混乱;同时POST请求没有给客户端返回任何响应(比如重定向或渲染结果),导致浏览器一直处于等待状态,出现挂起。
修复后的完整代码
// 通用函数:每次调用都会从数据库拉取最新用户数据 async function getUsers() { return new Promise((resolve, reject) => { const sql = "SELECT username, useremail, userage, useruniqueid FROM users"; db.query(sql, function(err, result) { if (err) reject(err); resolve(result); }); }); } // 首页路由:每次请求都获取最新用户数据并渲染 app.get("/", async(_req, res, next) => { try { const users = await getUsers(); res.render("home", { data: users }); } catch (err) { next(err); } }); // 添加新用户路由 app.post("/", async (req, res) => { // 解构获取请求参数 const { username, useremail, userage, useruniqueid } = req.body; try { // 等待插入数据库操作完成 await new Promise((resolve, reject) => { db.query('insert into users values(?,?,?,?)', [useruniqueid, username, useremail, userage], (err, result) => { if (err) reject(err); resolve(result); }); }); console.log('new user added'); // 插入完成后重定向到首页,触发GET请求拉取最新数据 res.redirect("/"); } catch (err) { console.log(err); res.status(500).send("添加用户失败"); } });
关键修改说明
- 移除全局缓存的
usersPromise:改用getUsers函数,每次请求页面时都会重新查询数据库,确保拿到最新数据。 - POST请求正确处理异步逻辑:用Promise包裹插入操作,等待数据库写入完成后再执行后续操作,避免异步时序问题。
- 遵循HTTP规范:添加用户完成后通过
res.redirect("/")让浏览器发起GET请求,重新渲染首页,此时会自动拉取最新的用户列表,同时解决了请求挂起的问题。 - 删除错误的重复路由注册:POST请求内不需要重新注册GET路由,原有GET路由已经能处理所有首页请求。
内容的提问来源于stack exchange,提问作者IoT-Practitioner
相关产品推荐
相关产品推荐

