Node.js中用HSCAN读取Redis哈希遇报错,求正确实现方案
问题描述
我通过HSET将用户对象存入Redis哈希,代码如下:
async (userObject) => { const { phone } = userObject; const key = keyGenerator.getUserAuthKey(phone); try { for (const [field,value] of Object.entries(userObject)) { await redisClient.HSET(key,field,value); } logger.info(`------ user data cached in redis successfully`); return true; } catch (error) { logger.error(`Error in saving user data in redis : ${error.message}`); throw error } }
之后编写了HSCAN读取函数,但运行时抛出错误:TypeError: Cannot read properties of undefined (reading 'length'),读取代码如下:
async function readRedisHashUsingHScan(hashKey) { let cursor = '0'; const result = {}; do { const reply = await redisClient.hScan(hashKey, cursor); const elements = reply[1]; cursor = reply.cursor; for (let i = 0; i < elements.length; i += 2) { result[elements[i]] = elements[i + 1]; } } while (cursor !== '0'); return result; }
报错原因
- 当目标哈希键不存在、哈希为空时,
reply[1]会返回undefined,此时读取elements.length会触发类型错误 - 原代码游标更新逻辑错误:多数Redis客户端(如ioredis)的
hScan返回值是[新游标, 字段值数组]结构,而非包含cursor属性的对象,这会导致游标无法正确更新,引发循环异常
修正后的读取函数
async function readRedisHashUsingHScan(hashKey) { let cursor = '0'; const result = {}; do { // 解构hScan返回的游标和字段值数组 const [newCursor, elements] = await redisClient.hScan(hashKey, cursor); cursor = newCursor; // 先校验elements是否为有效数组,避免读取undefined的length if (Array.isArray(elements) && elements.length > 0) { for (let i = 0; i < elements.length; i += 2) { const field = elements[i]; const value = elements[i + 1]; if (field !== undefined) { result[field] = value; } } } } while (cursor !== '0'); return result; }
额外优化建议
原存储代码循环调用HSET效率较低,可直接利用Redis HSET的批量设置特性,一次完成存储:
async (userObject) => { const { phone } = userObject; const key = keyGenerator.getUserAuthKey(phone); try { // 直接传入对象批量设置哈希字段 await redisClient.HSET(key, userObject); logger.info(`------ user data cached in redis successfully`); return true; } catch (error) { logger.error(`Error in saving user data in redis : ${error.message}`); throw error } }
内容的提问来源于stack exchange,提问作者18.5
相关产品推荐
相关产品推荐

