javascript - node.js redis 以及在使用模块时如何使用 promise

标签 javascript node.js redis promise q

我在 Node 服务器中有一个像这样的 Express 路由(需要文件):

var redis = require('../modules/redis');

module.exports = function (app) {

var redisClient = redis.init();


app.post('/auth/ticket', cors(), function (req, res) {


    var hashes = ['hash1','hash2', 'hash3'];

    var candidates = [];  // An array to collect valid hashes
    var key;  
    // to check each hash against a RedisDB I use a For Loop
    for (key in hashes) {
        var hash = hashes[key];
        console.log("Hash " + hash + "  will be proofed now:");
       //now I try to collect the valid hashes in the candidates array
       if (redisClient.exists(hash) === 1) candidates.push(hash);
    }
    console.log(JSON.stringify(candidates));
});
};

现在这是我的模块的代码,它将管理所有的 redis 请求:

exports.init = function () {
Redis = exports.Redis = function () {
    var promiseFactory = require("q").Promise,
        redis = require('promise-redis')(promiseFactory);

    this.client = redis.createClient();
    this.client.on('error', function (err) {
        console.log('redis error – ' + client.host + ':' + client.port + ' – ' + err);
    });

Redis.prototype.exists = function (key) {
    this.client.exists(key, function (err, data) {
       return data === 1 ? true : false;
    });
};

return new Redis();
};

所以我的经验是该模块能够正确地控制台记录结果。如果哈希有效,则返回 true,否则返回 false。这按预期工作。 问题是,for 循环继续执行而不获取结果。我认为这是由竞争条件引起的。

如您所见,我已经开始在我的代码顶部使用 Q 和 promise-redis 来锻炼一些东西:

 var promiseFactory = require("q").Promise,
    redis = require('promise-redis')(promiseFactory);

this.client = redis.createClient();

我想知道,我如何让我的 for 循环(在 Express 路由中)等待 redisClient.exists(hash) 的结果,或者换句话说,将所有有效的哈希值放入我的候选数组中。

请帮忙

最佳答案

就像@brad 说的,你可以使用Q.all,它会接受一个promises 数组作为输入,然后在所有promises 完成时返回一个结果数组:

你的回答有误:

Redis.prototype.exists = function (key) {

return this.client.exists(key)      // CHANGED, you still need to return a promise.
    .then(function (reply) {
        console.log("reply " + reply);
        return (reply);
    })
    .catch(console.log);

};

如果我没理解错的话,你想要的是这样的

exports.init = function () {
Redis = exports.Redis = function () {
    var Q = require("q"),
        promiseFactory = Q.Promise,
        redis = require('promise-redis')(promiseFactory);

    this.client = redis.createClient();
    this.client.on('error', function (err) {
        console.log('redis error – ' + client.host + ':' + client.port + ' – ' + err);
    });

Redis.prototype.exists = function (key) {
    return this.client.exists(key).then(function (data) {
       return data === 1 ? true : false;
    });
};

Redis.prototype.getActive = function (arry) {
    var self = this;
    return  Q.all(arry.map(self.exists.bind(self))
            ).then(function(res){
                return arry.filter(function(val, idx){ return res[idx];});
            });
};



return new Redis();
};

关于javascript - node.js redis 以及在使用模块时如何使用 promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30650499/

相关文章:

redis - 如何查看 Redis 何时/为何变慢/陷入困境?

javascript - 热模块更换——更新但不重新渲染

javascript - IE8 中的可打印旋转

node.js - 错误 'Can' 仅在 Cloud9 上发送后设置 header

node.js - socket.io 强制断开客户端

php - 如何在 PECL 上设置或跳过包配置?

javascript - 鼠标移动时增加两个 div 高度

javascript - 具有有限元素的列表轮换

node.js - Nodejs中变量赋值是同步的吗?

c++ - 让 credis 在 C++ 解决方案中工作