如何让Node.js中node-redis方法优先执行并获取返回结果?
这是典型的Node.js异步操作坑!你遇到的问题根源在于lrange是异步方法——它不会阻塞代码等待Redis返回结果,而是直接继续执行后面的同步代码,等Redis响应回来后才会触发回调函数里的逻辑。所以外部的console.log(addresses)先跑,这时候回调还没执行,addresses自然是空数组。
先还原你的代码和执行结果:
你的示例代码
var redis = require('redis'); var client = redis.createClient(); var addresses = new Array(); client.lrange('some_list', 0, -1, function(err, res) { console.log(res); // inner res.forEach(function(element) { if (result = element.match(/^(.+),(.*)$/)) { addresses.push(result[1]); } }); }); console.log(addresses); // outter
执行结果
[] // outter ['item1', 'item2', 'item3'] // inner
下面给你两种靠谱的解决方案,按需选择:
方案1:把依赖结果的逻辑放进回调里(基础写法)
既然回调是拿到Redis结果的地方,那所有需要用addresses的代码都直接写在回调内部就行:
var redis = require('redis'); var client = redis.createClient(); client.lrange('some_list', 0, -1, function(err, res) { // 一定要处理错误,不然出问题都不知道为啥! if (err) { console.error('获取Redis列表失败:', err); return; } console.log(res); // inner var addresses = []; res.forEach(function(element) { const match = element.match(/^(.+),(.*)$/); if (match) { addresses.push(match[1]); } }); // 在这里用addresses做你想做的事,比如打印、存数据库等等 console.log(addresses); });
方案2:用Promise + async/await(推荐,代码更清爽)
现在node-redis的新版本(v4+)已经原生支持Promise了,旧版本也可以用util.promisify转一下,这样就能用async/await写同步风格的异步代码:
v4+版本写法:
const redis = require('redis'); const client = redis.createClient(); // 先确保客户端连接成功 client.connect().then(async () => { try { // v4里方法名是驼峰式的lRange,注意和旧版本区分 const res = await client.lRange('some_list', 0, -1); console.log(res); // inner const addresses = res .map(element => { const match = element.match(/^(.+),(.*)$/); return match ? match[1] : null; }) .filter(Boolean); // 过滤掉匹配失败的项 console.log(addresses); // 这里可以直接return addresses给其他逻辑用 } catch (err) { console.error('获取列表失败:', err); } finally { // 记得用完断开连接 await client.disconnect(); } });
旧版本(v3及以下)写法:
const redis = require('redis'); const { promisify } = require('util'); const client = redis.createClient(); // 把回调风格的lrange转成Promise const lrangeAsync = promisify(client.lrange).bind(client); async function getAddresses() { try { const res = await lrangeAsync('some_list', 0, -1); console.log(res); // inner const addresses = []; res.forEach(element => { const match = element.match(/^(.+),(.*)$/); if (match) { addresses.push(match[1]); } }); console.log(addresses); return addresses; } catch (err) { console.error('获取列表失败:', err); throw err; // 把错误抛出去让上层处理 } } // 调用这个异步函数 getAddresses();
不管用哪种方案,都别忘记处理错误——异步操作很容易因为网络、Redis配置等原因出问题,不加错误处理的话排查起来会很头疼。
内容的提问来源于stack exchange,提问作者Feuda
相关产品推荐
相关产品推荐

