Node.js检查几个redis集中的值并同步返回

时间:2016-09-12 11:54:42

标签: javascript node.js asynchronous redis node-redis

我有7套,我需要至少在一个集合中检查值是否存在(sismember)并返回true或false。

我需要同步获得该值,如下所示:

const isExist = !!(_.max(_.range(7).map((day) => {
    redis.sismember(`blacklist${day}`, hashToken, function (err, res) {
       return res;
    });
})));

2 个答案:

答案 0 :(得分:2)

你可以避免使用同步代码。

在这种情况下,我建议使用Promises来管理七个redis请求。

Bluebird promise library可以使大多数API在一行代码中保证兼容(阅读promisification),redis的API也不例外。 (Bluebird的文档甚至uses redis as an examplenode-redis documentation也是如此,所以如果你关心那种事情,它甚至会“正式支持”。)

所以你似乎想要的是一个函数,它可以检查最多7个sismember的异步调用,并在第一个结果为肯定时解析为总结果 - Promise#any()可以那样做。

var Promise = require('bluebird');
var _ = require('lodash');
var redis = require('redis');

Promise.promisifyAll(redis);

function checkBlacklist(hashToken) {
    var blacklistChecks = _.range(7).map((day) => {
        return redis.sismemberAsync(`blacklist${day}`, hashToken);
    });
    return Promise.any(blacklistChecks);
}

使用

checkBlacklist('some_token').then((result) => {
   // do something with the result
}).catch((err) => {
   // an error has occurred - handle it or rethrow it
});

答案 1 :(得分:0)

如果涉及多个redis操作,通常我更喜欢编写lua脚本然后通过我的nodejs程序调用它。这是一个不相关的例子,但它显示了如何使用lua到nodejs。

示例:get_state.lua

local jobId = KEYS[1]
local jobExists = redis.pcall('exists', jobId)
if jobExists == 0 or jobExists == nil then
  return 404  -- not found.
end

-- check the job state
local st = tonumber(redis.pcall('hmget', jobId, 'ctlState')[1])
if st == nil then
  st = 12002  -- job running, unless explicitly stated otherwise
end
return st

使用lua的NodeJS代码:比如index.js

...
// List of script files 
var scriptMap = { 
  getState: {file:'./scripts/get_state.lua'}
};


...

// A function to load the script file to Redis and cache the sha.
function loadScript(script) {
  logger.trace("loadScript(): executing...");
  if (scriptMap[script]['hash']) {
    logger.trace("Sript already loaded. Returning without loading again...");
    return Promise.resolve(scriptMap[script]['hash']);
  }

  //load from file and send to redis
  logger.trace("Loading script from file %s...", scriptMap[script].file);
  return fs.readFileAsync(scriptMap[script].file).then(function(data) {
    return getConnection().then(function(conn) {
      logger.trace("Loading script to Redis...");
      return conn.scriptAsync('load', data)
    })
  })
}

最后,一个使用缓存的sha摘要来执行脚本的函数:

getJobState: function(jobId) {
    return loadScript('getState').then(function(hash) {
      return getConnection().then(function (conn) {
        return conn.evalshaAsync(hash, 1, jobId)
      })
    })
  },