2012-11-15 15 views
8

Próbuję uzyskać kilka wartości z Redis, połączyć je i ostatecznie wysłać. Ale po prostu nie mogę spełnić tych obietnic.nodejs redis Q obiecuje, jak to działa?

To proste get funkcje z 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 
}); 

Teraz chcę dostać ID i username i wysłać je, ale nie mam pojęcia jak zrobić tę pracę. Udaje mi się, że praca z wywołań zwrotnych, ale jest to wynik bardzo brudny, więc Potem próbował owinąć funkcji anonimowych w Q.fcall i po wywołaniu .then który wygląda coś takiego

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

ale to daje mi błąd o zbyt wielu argumentów został przyjęty i nie jestem nawet pewien, czy to mi pomoże, nawet gdyby to zadziałało.

Odpowiedz

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 
}); 

Zobacz https://github.com/kriskowal/q#adapting-node

+0

, który wydaje się być miłe podejście i działa dobrze, chociaż ja wciąż brakuje część jak mogę połączyć identyfikator i nazwę użytkownika w jednym obiekcie na wysyłanie do przeglądarki bez zbytniego bałaganu. Czy mógłbyś podzielić się tutaj pewną wiedzą? – Giedrius

+0

Co powiesz na to? –

+0

Dziękuję bardzo, teraz te obietnice zaczynają mieć dla mnie większy sens. – Giedrius

0

Używam prostego modułu RequireJS korzystając Node-Redis i whenjs stworzenia podnoszony Redis Wrapper:

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} 

Użycie jest bardzo proste:

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

Korzystanie obietnicy Bluebird i 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);