使用Express+Redis开发登录页面无法正确获取Redis返回值如何解决
问题排查与修复方案
根因分析
该问题是JavaScript异步执行机制导致的:
redis.get()属于异步IO操作,调用后不会立即执行传入的回调函数,而是先将回调放入任务队列,继续执行后续的同步代码- 你写在
redis.get()外部的console.log(ans)是同步代码,会在回调执行前就运行,此时回调内的ans = true逻辑还未触发,所以永远打印初始值false
修复方案
方案1:回调内处理逻辑
所有依赖Redis查询结果的操作,全部放到回调函数内部执行:
app.get('/enter', (req, res) => { const username = req.query.user; const password = req.query.pass; let ans = false; redis.get(username, function(err, reply) { // 补充错误处理,避免服务异常无响应 if (err) { return res.status(500).send('服务内部错误'); } if(reply != null ) ans = true; console.log(ans); // 后续登录校验、响应返回等逻辑都写在此处 if (ans) { // 可补充密码校验逻辑 res.send('登录成功'); } else { res.send('用户名不存在'); } }) })
方案2:async/await语法优化(更推荐)
主流Redis客户端都支持Promise调用,可改用async/await语法让异步逻辑的书写顺序和执行顺序一致,可读性更高:
// 接口处理函数前加async关键字 app.get('/enter', async (req, res) => { const username = req.query.user; const password = req.query.pass; let ans = false; try { // 用await等待Redis查询完成 const reply = await redis.get(username); if(reply != null ) ans = true; console.log(ans); // 后续逻辑可按同步顺序书写 } catch (err) { return res.status(500).send('服务内部错误'); } })
内容的提问来源于stack exchange,提问作者Gidon Avziz
相关产品推荐
相关产品推荐

