На първо място, проблемът във вашия въпрос е, че вътре в for
цикъл, client.get
се извиква с асинхронен обратно извикване, където синхронен for
цикълът няма да чака асинхронното обратно извикване и следователно следващия ред res.json({data:jobs});
се извиква веднага след for
цикъл преди асинхронните обратни извиквания. В момента на реда res.json({data:jobs});
се извиква, масивът jobs
все още е празен []
и се връща с отговора.
За да смекчите това, трябва да използвате всякакви обещаващи модули като async
, bluebird
, ES6 Promise
и др.
Модифициран код с помощта на асинхронен модул,
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
документация, се забелязва, че използването на Keys е предназначено за отстраняване на грешки и специални операции, като промяна на оформлението на вашето ключово пространство и не е препоръчително за производствени среди.
Следователно бих предложил да използвате друг модул, наречен redisscan, както е по-долу, който използва SCAN
вместо 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();
}
});