redis模块和ioredis的注意事项
文章目录
- redis模块和ioredis的注意事项
- 前言
- 一、ioredis和redis使用zrange的比较
- 二、出现zrange结果不同的原因
- 总结
前言
node.js在使用redis的时候有两个库可以选择,一个是redis
、另一个是ioredis
,我一直以来也没有太大关注这两个库有什么区别。直到今天写代码的时候发现一个令我困惑的问题。
一、ioredis和redis使用zrange的比较
有个需求,需要将任务按优先级进行排序,在redis是有一个有序集合的api:zadd
可以直接完成这个功能的。在zadd
中主要通过参数priority来完成数据的自动排序,排序规则是,priority的值越小,score越小,代码如下:
const Redis = require('ioredis');
const redis1 = new Redis();
// 使用 zadd 命令
async function addToSortedSet() {
try {
const result = await redis1.zadd('mySortedSet', 1, 'value1');
const result1 = await redis1.zadd('mySortedSet', 3, 'value12');
} catch (err) {
console.error('Error adding to sorted set:', err);
}
}
addToSortedSet();
然后取数据
const result = await redis1.zrange('manager_processing', 0, 0);
console.log('取出result:', result); //正常返回接结果
打印结果
这一切都没有什么问题,很正常。
BUT, 当我们用redis模块来实现时,问题就来了
const Redis = require('redis');
var client = Redis.createClient(6379,'127.0.0.1'); //端口号、主机
// 使用 zadd 命令
async function addToSortedSet() {
try {
const result = await client.zadd('mySortedSet', 1, 'value4');
const result1 = await client.zadd('mySortedSet', 3, 'value5');
} catch (err) {
console.error('Error adding to sorted set:', err);
}
}
addToSortedSet();
可以看出redis模块实现插入数据是没有问题的,如下图,数据成功插入。
但是当我们去取数据的时候,注意:
try {
const result = await client.zrange('manager_processing', 0, 0);
console.log('取出result:', result); //结果是true or flase
}catch (e) {
console.log(e);
}
**返回结果竟然是false!!!!!!!
**这是为什么???卖个关子,我们在下一节给出解释。
二、出现zrange结果不同的原因
redis
(redis.createClient
):
redis
库创建的client
是基于回调的 Redis 客户端。要使用await
关键字,它必须返回一个 Promise。redis
库的zrange
方法是基于回调的,不直接支持 Promise。- 在
client.zrange
中,虽然你使用了await
,但由于client.zrange
返回的是回调模式的函数,这会导致TypeError
,因为await
不能用于非 Promise 对象。
ioredis
(new Redis()
):
ioredis
库创建的redis1
客户端支持 Promise,所以可以直接使用await
来处理异步操作。redis1.zrange
调用将正确返回 Promise 的结果,并可以被await
使用。
明白了把,在redis模块中,redis的库的 zrange 方法是基于回调的,不直接支持 Promise,他不能使用await去获取返回值哦,原来真正的罪魁祸首是,redis的库是基于回调的,不支持promise。
找出原因,这下我们就可以修改redis的代码了:
const Redis = require('ioredis');
const redis1 = new Redis();
var redis = require('redis');
var client = redis.createClient(6379,'127.0.0.1'); //端口号、主机
async function testZrange() {
client.zrange('manager_processing', 0, 0, (err, result)=> {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
}
这样我们就可以取到结果了。完美解决。
当然还有另一种用法:
const result = await new Promise((resolve, reject) => {
redisClient.zrange(manager_processing, 0, 0, (err, result) => {
if (err) {
reject(err);
} else {
resolve(result);
}
});
});
以上两种方法大家可以根据自己需求去选择使用。
总结
-
redis 库创建的 client 是基于回调的 Redis 客户端。要使用 await 关键字,它必须返回一个 Promise。redis 库的 zrange 方法是基于回调的,不直接支持 Promise。
-
ioredis 库创建的 redis1 客户端支持 Promise,所以可以直接使用 await 来处理异步操作。