nodejs redis Q promises,如何让它工作?

时间:2012-11-15 01:04:50

标签: node.js redis promise q

我试图从redis中获取一些值,将它们组合起来并最终发送。但我不能让这些承诺奏效。

这是redis的简单get函数

client.get('user:1:id',function(err,data){
    // here I have data which contains user ID
});
client.get('user:1:username',function(err,data){
    // here I have data which contains username
});

现在我希望得到IDusername并发送给他们,但我不知道如何做到这一点。我设法让它与回调一起使用,但结果非常混乱,所以我试图将匿名函数包装到Q.fcall中,并在调用.then后看起来像那样

client.get('user:1:id',Q.fcall(function(err,data){
    return data;
}).then(function(val) {
   // do something
}));

但这给了我太多参数传递的错误,我甚至不确定这是否对我有帮助,即使它能起作用。

3 个答案:

答案 0 :(得分:10)

Q.all([Q.ninvoke(client, 'get', 'user:1:id'),
       Q.ninvoke(client, 'get', 'user:1:username')]).then(function (data) {
  var id = data[0];
  var username = data[1];
  // do something with them
});

请参阅https://github.com/kriskowal/q#adapting-node

答案 1 :(得分:0)

我使用一个简单的RequireJS模块,使用 node-redis whenjs 来创建一个提升的redis包装器:

define [
  'redis/lib/commands'
  'when'
  'when/node/function'
], (Commands, When, NodeFn) ->
  'use strict'

  lift = (redis) ->
    wrapped = {}
    Commands.map (cmd) ->
      wrapped[cmd] = (args...) ->
        def = When.defer()
        args.push NodeFn.createCallback def.resolver
        redis[cmd].apply redis, args
        def.promise
    wrapped

  {lift}

用法很简单:

client = lift redis.createClient()
client.get("hello").then console.log, console.error

答案 2 :(得分:0)

使用Promise,Bluebird和node_redis:

import { RedisClient, createClient, ClientOpts } from "redis";
import { promisifyAll, PromisifyAllOptions } from "bluebird";


export module FMC_Redis {

    export class Redis {
        opt: ClientOpts;
        private rc: RedisClient;
        private rcPromise: any;

        private static _instance: Redis = null;
        public static current(_opt?: ClientOpts): Redis {

            if (!Redis._instance) {
                Redis._instance = new Redis(_opt);
                Redis._instance.redisConnect();
            }
            return Redis._instance;
        }

        public get client(): RedisClient {
            if (!this.rc.connected) throw new Error("There is no connection to Redis DB!");
            return this.rc;
        }

        /******* BLUEBIRD ********/
        public get clientAsync(): any {
            // promisifyAll functions of redisClient 
            // creating new redis client object which contains xxxAsync(..) functions.
            return this.rcPromise = promisifyAll(this.client);
        }

        private constructor(_opt?: ClientOpts) {
            if (Redis._instance) return;

            this.opt = _opt
                ? _opt
                : {
                    host: "127.0.0.1",
                    port: 6379,
                    db: "0"
                };
        }

        public redisConnect(): void {
            this.rc = createClient(this.opt);
            this.rc
                .on("ready", this.onReady)
                .on("end", this.onEnd)
                .on("error", this.onError);
        }

        private onReady(): void { console.log("Redis connection was successfully established." + arguments); }
        private onEnd(): void { console.warn("Redis connection was closed."); }
        private onError(err: any): void { console.error("There is an error: " + err); }


        /****** PROMISE *********/
        // promise redis test
        public getRegularPromise() {
            let rc = this.client;
            return new Promise(function (res, rej) {
                console.warn("> getKeyPromise() ::");
                rc.get("cem", function (err, val) {
                    console.log("DB Response OK.");
                    // if DB generated error:
                    if (err) rej(err);
                    // DB generated result:
                    else res(val);
                });
            });
        }


        /******* ASYNC - AWAIT *******/
        // async - await test function
        public delay(ms) {
            return new Promise<string>((fnResolve, fnReject) => {
                setTimeout(fnResolve("> delay(" + ms + ") > successfull result"), ms);
            });
        }

        public async delayTest() {
            console.log("\n****** delayTest ")
            let a = this.delay(500).then(a => console.log("\t" + a));

            let b = await this.delay(400);
            console.log("\tb::: " + b);
        }

        // async - await function
        public async getKey(key: string) {
            let reply = await this.clientAsync.getAsync("cem");
            return reply.toString();
        }
    }
}

let a = FMC_Redis.Redis.current();
// setTimeout(function () {
//     console.warn(a.client.set("cem", "naber"));
//     console.warn(a.client.get("cem"));
//     console.warn(a.client.keys("cem"));
// }, 1000);

/***** async await test client *****/
a.delayTest();


/** Standart Redis Client test client */
setTimeout(function () {
    a.client.get("cem", function (err, val) {
        console.log("\n****** Standart Redis Client")
        if (err) console.error("\tError: " + err);
        else console.log("\tValue ::" + val);
    });
}, 100)

/***** Using regular Promise with Redis Client > test client *****/
setTimeout(function () {
    a.getRegularPromise().then(function (v) {
        console.log("\n***** Regular Promise with Redis Client")
        console.log("\t> Then ::" + v);
    }).catch(function (e) {
        console.error("\t> Catch ::" + e);
    });
}, 100);

/***** Using bluebird promisify with Redis Client > test client *****/
setTimeout(function () {
    var header = "\n***** bluebird promisify with Redis Client";
    a.clientAsync.getAsync("cem").then(result => console.log(header + result)).catch(console.error);
}, 100);

enter image description here