2012-11-15 48 views
8

我想從redis獲取一些值,將它們結合起來並最終發送。但我不能讓這些承諾奏效。nodejs redis Q承諾,如何使它工作?

這是一個簡單的get功能從Redis的

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和它看起來像那

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

但是,讓我錯誤的參數太多調用.then後已經通過了,我甚至不知道這是否會幫助我,即使它會奏效。

回答

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

+0

,這似乎是一個不錯的方法,而且效果很好,但我仍然失蹤的一部分,我怎麼能結合ID和用戶名在一個對象發送到瀏覽器而不會讓事情太雜亂。你能分享一些知識嗎? – Giedrius

+0

那怎麼樣? –

+0

非常感謝,現在這些承諾開始對我更有意義。 – Giedrius

0

我使用使用節點redis的whenjs創建擡起redis的包裝的簡單RequireJS模塊:

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 
0

使用無極,藍鳥和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);