【问题标题】:nodejs redis Q promises, how to make it work?nodejs redis Q 承诺,如何使它工作?
【发布时间】:2012-11-03 14:43:10
【问题描述】:

我试图从 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
}));

但是由于传递了太多参数,这给了我错误,我什至不确定这是否会帮助我,即使它会起作用。

【问题讨论】:

    标签: node.js redis promise q


    【解决方案1】:
    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

    【讨论】:

    • 这似乎是一种不错的方法,并且效果很好,尽管我仍然缺少如何将 id 和 username 组合在一个对象中以发送到浏览器而不会使事情变得太混乱的部分。请您在这里分享一些知识。
    • 非常感谢,现在这些承诺对我来说开始更有意义了。
    • 您可以使用 Q.spread 挤出更多。 Q.spread([Q.ninvoke(client, "get", "user:1:id"), Q.ninvoke(client, "get", "user:1:username"], function (id, username) { })。
    • 我希望我能多次支持你。我用它来回答我自己的 Stack Overflow 问题:stackoverflow.com/questions/34902092/…
    【解决方案2】:

    我使用一个简单的 RequireJS 模块,使用 node-rediswhenjs 创建一个提升的 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
    

    【讨论】:

      【解决方案3】:

      使用 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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-04
        • 1970-01-01
        • 2016-05-18
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 2015-02-25
        • 2015-05-12
        相关资源
        最近更新 更多