背景
redis数据库连接建立
var redis = require('redis'),
RDS_PORT = 6379,
RDS_HOST = '127.0.0.1',
RDS_OPTS = {},
client = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS);
client.on('ready', function(res) {
console.log('ready')
});
之后可以通过client.get进行对redis键的索引。当我们用一个键值对存储一个帖子的内容,并且同时要索引多个帖子的内容时,容易直观地写出以下代码
function fn(keys){
let result = []
keys.forEach(e => {
client.get(e, (error, res) => {
result.push(res)
})
})
return result
}
其中keys表示键名数组。但事实上client.get是一个异步任务,这个函数会直接返回空数组
递归解决方案
function fn(result, index, keys) {
client.get(keys[index], (error, res) => {
result.push(res)
if (index != keys.length - 1) {
return fn(result, index + 1, keys)
} else {
return result
}
});
}
const result = fn([], 0, ['key1', 'key2', 'key3']) //使用
非递归解决方案
anyway,总觉得通过递归解决一些问题(包括二叉树的遍历)有点儿逃避的感觉。虽说JavaScript也支持尾递归优化,但是用递归还是容易写出性能不高的解决方案。因此实现了一个非递归的方法
function fn(keys){
let promiseTask = []
let result = []
keys.forEach(e => {
let p = new Promise((resolve, reject) => {
client.get(e, (error, res) => {
result.push(res)
resolve()
})
})
promiseTask.push(p)
})
Promise.all(promiseTask).then(() => {
return result
})
}
const result = fn(['key1', 'key2', 'key3']) //使用
一点补充
在实际开发场景中,一般不会直接将取到的键值添加到结果数组,通常要经过某些处理或者过滤。因此建议在函数fn中增加一个参数,用于接收对键值进行处理的方法。这样代码整体结构分明,维护方便。