Redis缓存报错TypeError: client.getAsync is not a function的解决方法
问题修复方案
错误根源
你的代码存在两个核心问题:
promisifyAll调用时机错误:你把它放在了connect事件回调里,此时Redis客户端实例已经创建完成,无法给已存在的client添加getAsync这类异步方法。promisifyAll作用对象错误:直接对整个redis模块执行promisify无效,需要针对客户端实例或其原型操作。
修复方案一:正确使用Bluebird promisifyAll
调整promisify的时机和作用对象,确保所有客户端方法都被异步化:
const redis = require('redis') const bluebird = require('bluebird') // 先对Redis客户端原型做promisify,后续创建的所有client都会自动带Async方法 bluebird.promisifyAll(redis.RedisClient.prototype) bluebird.promisifyAll(redis.Multi.prototype) // 再创建Redis客户端实例 const client = redis.createClient() client.on('connect', () => { console.log('[PASS]'.green + ' Redis Connected') }) // 监听Redis错误,避免崩溃 client.on('error', (err) => { console.error('[FAIL] Redis Error:', err) }) router.get('/', async (req, res) => { // 补充:从请求中获取offerID(根据你的路由规则调整,比如params/query) const offerID = req.query.offerID if (!offerID) return res.sendStatus(400) try { const offerData = await client.getAsync(offerID) let link if (offerData) { link = JSON.parse(offerData) } else { link = await Offers.findOne({_id: offerID}) if (link == null) return res.sendStatus(404) // 用setAsync保持异步风格,建议添加过期时间避免数据过时 await client.setAsync(offerID, JSON.stringify(link)) await client.expireAsync(offerID, 3600) // 缓存1小时 } // 后续业务逻辑 res.json(link) } catch (err) { console.error('Request Error:', err) res.sendStatus(500) } })
修复方案二:使用Redis v4+原生Promise API(推荐)
新版Redis客户端(v4及以上)原生支持Promise,无需依赖Bluebird,代码更简洁:
// v4+版本的引入方式不同 const { createClient } = require('redis') // 创建客户端(根据你的Redis地址配置参数) const client = createClient({ url: 'redis://localhost:6379' }) // 主动连接Redis client.connect() .then(() => console.log('[PASS]'.green + ' Redis Connected')) .catch(err => console.error('[FAIL] Redis Connection Error:', err)) // 监听Redis错误 client.on('error', (err) => { console.error('[FAIL] Redis Error:', err) }) router.get('/', async (req, res) => { const offerID = req.query.offerID if (!offerID) return res.sendStatus(400) try { const offerData = await client.get(offerID) let link if (offerData) { link = JSON.parse(offerData) } else { link = await Offers.findOne({_id: offerID}) if (link == null) return res.sendStatus(404) await client.set(offerID, JSON.stringify(link)) await client.expire(offerID, 3600) // 缓存1小时 } res.json(link) } catch (err) { console.error('Request Error:', err) res.sendStatus(500) } })
额外注意事项
- 必须补充
offerID的获取逻辑,否则会出现未定义错误。 - 建议给缓存设置过期时间,避免数据库更新后缓存数据过时。
- 务必添加Redis错误监听,防止连接异常导致服务崩溃。
内容的提问来源于stack exchange,提问作者Anon
相关产品推荐
相关产品推荐

