Node.js中Redis客户端GET方法未执行,求排查方案
问题分析及解决方案
核心问题
- 混用回调与async/await:Redis v4+客户端方法在传入回调时不会返回Promise,你写的
await redisClient.get(...)完全无效,回调函数也无法被正确触发,这就是只打印console log one的根本原因。 - 未等待Redis连接就绪:
redisClient.connect()是异步操作,虽然Redis有命令队列缓冲机制,但这种不可靠的处理可能导致部分命令无法正常执行。 - MongoDB查询同样混用await与回调:
ProductPrices.find(...).exec(callback)写法下,await不起作用,因为传入回调时exec不会返回Promise,会导致逻辑混乱。 - 条件判断逻辑错误:你判断
productId != null,但productId来自路由参数必然不为空,应该判断缓存的history是否存在。
修正后的代码
const Redis = require('redis') const ProductPrices = require('你的模型路径') const errorHandler = require('你的错误处理器路径') const redisClient = Redis.createClient({ url: 'redis://*****:*****@redis-******.cloud.redislabs.com:16564' }) // 异步等待Redis连接完成,建议在项目入口执行 (async () => { try { await redisClient.connect() console.log('Redis连接成功') await redisClient.set('name', 'Steph') } catch (err) { console.error('Redis连接失败:', err) } })() redisClient.on('error', (err) => console.log('Redis Client Error', err)); router.get('/market/product/:slug', async (req,res) => { const productId = req.params.slug console.log('console log one') try { // 用async/await获取Redis值,放弃回调 const history = await redisClient.get(productId) console.log('console log two') if (history) { console.log('console log three') res.json(JSON.parse(history)) } else { console.log('console log four') // MongoDB查询用await,不用exec回调 const data = await ProductPrices.find({ productId }) .lean() .sort({ date: 1 }) // 存入Redis并设置过期时间(示例为3600秒),避免数据过期 await redisClient.setEx(productId, 3600, JSON.stringify(data)) res.json(data) } } catch (error) { console.error('请求处理错误:', error) return res.status(400).json({ error: errorHandler(error) }) } })
关键优化说明
- 全程用
async/await处理异步操作,彻底避免回调混用的问题。 - 显式等待Redis连接完成后再执行命令,保证操作可靠性。
- 修正条件判断逻辑,改为检查缓存值是否存在。
- 用
setEx替代set,给缓存添加过期时间,防止数据长期失效未更新。 - 全局try/catch捕获异常,统一处理错误响应。
内容的提问来源于stack exchange,提问作者Stephanie Cherry
相关产品推荐
相关产品推荐

