2016-09-12 37 views
0

私は7つのセットを持っています。値が存在するかどうかをチェックして、少なくとも1つのセットで(true)またはfalseを返す必要があります。Node.js少数の赤いセットの値をチェックして同期的に返します

私はこのように、同期的にその値を取得する必要があります:あなたはそれを避けることができるとき

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

ルアスクリプトでクエリredis-sideを実行できますか? –

+0

@ChrisTannerいいえ、申し訳ありませんが、できません。私はnode.jsサーバーでそれを行う必要があります。 –

+0

redisに7回のラウンドトリップを実行する代わりに、この操作をアトミックに行うことができるluaスクリプトの使用を検討してください。このようにして、あなたのチェック操作が他のクライアントコードによって中断されないことを確かめます。 –

答えて

2

あなたは同期コードをしたいことはありません。

この場合は、7回の要請を管理するために約束を使用することをお勧めします。

Bluebird promise libraryは、ほとんどのAPIを1行のコード(約promisificationを読む)で約束できるようにすることができます.RedisのAPIも例外ではありません。 (あなたがそういったことの世話場合、それは、でも「公式にサポートされている」ですので、ブルーバードのドキュメントそうでもuses redis as an example、とは、node-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 
}); 
0

複数のRedisのオペレーションが含まれている場合は、一般的に私はLuaのスクリプトを記述して、私のnodejsプログラムを通してそれを呼び出すことを好みます。これは無関係の例ですが、luaからnodejまでの使用方法を示しています。

例:LUAを使用しています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 

NodeJSコード:

... 
// 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) 
    }) 
    }) 
} 

index.js言うそして、最後に、キャッシュされたSHAを使用する機能は、スクリプトを実行するためにダイジェスト:

getJobState: function(jobId) { 
    return loadScript('getState').then(function(hash) { 
     return getConnection().then(function (conn) { 
     return conn.evalshaAsync(hash, 1, jobId) 
     }) 
    }) 
    }, 
関連する問題