更好的方式来编写一个简单的节点redis循环(使用ioredis)?

所以,我还在用其他语言很久以前学习JS / Node的方法。

我有一个很小的微型服务,从一个redis频道读取,temp将它存储在一个工作频道中,完成工作,删除它,然后继续。 如果频道中有更多,则立即重新运行。 如果没有,它会设置一个超时,并在1秒内再次检查。

它工作正常…但超时轮询似乎并不是“正确”的方法来解决这个问题。 我还没有find很多有关使用BRPOPLPUSH来尝试阻止(与RPOPLPUSH)并在Node ….或其他选项中等待。 (Pub / Sub在这里不是一个选项…这是唯一的监听者,它可能并不总是在监听。)

以下是我正在做的简短的本质:

var Redis = require('ioredis'); var redis = new Redis(); var redisLoop = function () { redis.rpoplpush('channel', 'channel-working').then(function (result) { if (result) { processJob(result); //do stuff //delete the item from the working channel, and check for another item redis.lrem('channel-working', 1, result).then(function (result) { }); redisLoop(); } else { //no items, wait 1 second and try again setTimeout(redisLoop, 1000); } }); }; redisLoop(); 

我觉得我错过了一些非常明显的东西。 谢谢!

BRPOPLPUSH不在Node中阻塞,在客户端阻塞。 在这种情况下,我认为这正是你需要摆脱投票。

 var Redis = require('ioredis'); var redis = new Redis(); var redisLoop = function () { redis.brpoplpush('channel', 'channel-working', 0).then(function (result) { // because we are using BRPOPLPUSH, the client promise will not resolve // until a 'result' becomes available processJob(result); // delete the item from the working channel, and check for another item redis.lrem('channel-working', 1, result).then(redisLoop); }); }; redisLoop(); 

请注意, redis.lrem是asynchronous的,因此您应该使用lrem(...).then(redisLoop)确保只有在项目从channel-working成功删除后才会执行下一个滴答。