Redis client.set正常但client.get失效问题(附Node.js代码)
问题排查:Redis缓存中间件client.get无法正常工作
问题代码
async function getRepos(req, res, next) { try { console.log('Fetching Data...'); const { username } = req.params; const response = await fetch(`https://api.github.com/users/${username}`); const data = await response.json(); const repos = data.public_repos; // Set data to Redis await client.setex(username, 3600, repos); res.send(setResponse(username, repos)); } catch (err) { console.error(err); res.status(500); } } // Cache middleware async function cache(req, res, next) { const { username } = req.params; console.log(username) await client.get(username, (err, data) => { if (err) throw err; if (data !== null) { res.send(setResponse(username, data)); } else { next(); } }); }
核心问题原因
Async/Await与回调函数混用
cache函数是async函数,但调用client.get时传入了回调。Redis客户端的get方法在传入回调时会以回调模式执行,此时await不会等待回调逻辑完成,函数会直接执行完毕,后续回调代码可能在请求响应发送后才触发,导致缓存逻辑完全失效。未捕获的异步异常
回调内的throw err会抛出未捕获的异步异常,async函数无法捕获回调内部的错误,这会导致进程崩溃或请求挂起,无法正常返回响应。Redis客户端Promise兼容性问题
若使用的Redis客户端(如ioredis、node-redis v4+)支持Promise API,回调模式的使用会破坏异步流程的可控性,这是中间件逻辑异常的关键。
修复方案
将client.get改为Promise方式调用,用async/await正确等待缓存读取完成,并通过try/catch捕获错误:
async function cache(req, res, next) { const { username } = req.params; console.log(username); try { // 用Promise方式读取缓存,await等待结果 const data = await client.get(username); if (data !== null) { // Redis存储的是字符串,需转为数字类型匹配存入时的格式 const reposCount = parseInt(data, 10); res.send(setResponse(username, reposCount || data)); } else { // 缓存不存在,进入下一个中间件 next(); } } catch (err) { console.error('缓存读取失败:', err); res.status(500).send('服务器缓存错误'); } }
额外注意点
- Redis存储的所有值都是字符串类型,存入的
public_repos是数字,取出时会变成字符串。如果setResponse期望数字类型,必须用parseInt或Number转换,避免返回数据类型不一致。 - 确认Redis客户端版本支持Promise API(node-redis v4+默认支持,v3及以下需手动启用Promise模式)。
内容的提问来源于stack exchange,提问作者trek lucifer
相关产品推荐
相关产品推荐

