我正在使用javascript创建节点API。我使用redis作为我的键值存储。 我在我的应用程序中创建了一个redis-client,并且能够获得特定密钥的值。
我想检索所有键及其值。 我做到了这一点:
app.get('/jobs', function (req, res) {
var jobs = [];
client.keys('*', function (err, keys) {
if (err) return console.log(err);
if(keys){
for(var i=0;i<keys.length;i++){
client.get(keys[i], function (error, value) {
if (err) return console.log(err);
var job = {};
job['jobId']=keys[i];
job['data']=value;
jobs.push(job);
});
}
console.log(jobs);
res.json({data:jobs});
}
});
});
但我总是得到空白数组作为回应。
有没有办法在javascript中执行此操作?
由于
答案 0 :(得分:10)
首先,您的问题中的问题是,在for
循环内,使用异步回调调用client.get
,其中同步 for
循环不会等待异步回调,因此在异步回调之前的res.json({data:jobs});
循环之后立即调用下一行for
。在调用行res.json({data:jobs});
时,数组jobs
仍为空[]
并返回响应。
要缓解这种情况,您应该使用任何承诺模块,例如async
,bluebird
,ES6 Promise
等。
使用Dojo模块修改代码,
app.get('/jobs', function (req, res) {
var jobs = [];
client.keys('*', function (err, keys) {
if (err) return console.log(err);
if(keys){
async.map(keys, function(key, cb) {
client.get(key, function (error, value) {
if (error) return cb(error);
var job = {};
job['jobId']=key;
job['data']=value;
cb(null, job);
});
}, function (error, results) {
if (error) return console.log(error);
console.log(results);
res.json({data:results});
});
}
});
});
但是从
Redis
async开始,观察到了使用。{ 密钥用于调试和特殊操作,例如 更改键空间布局,不建议生产 的环境中。
因此,我建议使用另一个名为documentation的模块,如SCAN
redisscan中建议的那样使用KEYS
代替Redis
。
类似的东西,
var redisScan = require('redisscan');
var redis = require('redis').createClient();
redisScan({
redis: redis,
each_callback: function (type, key, subkey, value, cb) {
console.log(type, key, subkey, value);
cb();
},
done_callback: function (err) {
console.log("-=-=-=-=-=--=-=-=-");
redis.quit();
}
});
答案 1 :(得分:2)
你永远不应该这样做。首先,不建议在生产中使用KEYS *
。其次,这不会扩展(集群)。
您可以将缓存的条目组织到SET中并查询SET中的项目,然后检索引用键。这也使失效更容易。
查看一些数据存储最佳实践。
https://redis.io/topics/data-types-intro how to get all keys and values in redis in javascript?
答案 2 :(得分:1)
这将获得所有键但没有值:
const redis = require('redis');
const client = redis.createClient();
client.keys('*', (err, keys) => {
// ...
});
现在您需要以通常的方式获取这些键的值。例如:
Promise.all(keys.map(key => client.getAsync(key))).then(values => {
// ...
});
或使用async
模块或以您喜欢的任何方式。
答案 3 :(得分:1)
2个请求的组合:
import * as ioredis from 'ioredis';
const redis = new ioredis({
port: redisPort,
host: redisServer,
password: '',
db: 0
});
const keys = await redis.collection.keys('*');
const values = await redis.collection.mget(keys);
两个阵列的顺序都相同。
答案 4 :(得分:0)
您可以在此链接中找到有用的内容
https://github.com/NodeRedis/node_redis/tree/master/examples