2016-08-20 3 views
1

nodejs 및 redisdb에서의 개발 과정을 배우고 있습니다. 나는 익스프레스 프레임 워크에있다.redis 메서드를 동 기적으로 호출

문제 : 키 사용자 ID가있는 해시에 일부 사용자 정보가 있다고 가정 해 봅니다. 마지막으로 로그인 한 키 user_lastlogged : user_id보다 user_favourites : user_id에 자신이 가장 좋아하는 항목이 있습니다.

사용자 세부 정보, 마지막 로그인 시간 및 그의 fav와 함께 페이지를 렌더링하고 싶습니다. 노드 js의 항목.

나는이 같은 것을 사용할 것이지만, 물론 작동하지 않을 것이다. 왜냐하면 메소드 콜백은 비동기 적으로 실행되기 때문이다.

var redis = require("redis"); 
var client = redis.createClient(); 

router.get('/', function (req, res, next) { 

    var userId='1'; 

    var returnHtml = ''; 

    client.hgetall('user:'+userId, function(err,objects){ 
    returnHtml+=utils.inspect(objects); 
    }); 

    client.hgetall('user_lastlogged:'+userId, function(err,objects){ 
    returnHtml+=utils.inspect(objects); 
    }); 

    client.hgetall('user_favourites:'+userId, function(err,objects){ 
    returnHtml+=utils.inspect(objects); 
    }); 

    res.send(returnHtml); 

}); 

지금은 적절한 redis 데이터 유형 등을 무시하십시오.

node.js에서 이러한 종류의 작업이 일반적으로 어떻게 해결됩니까? 아니면 express js 프레임 워크에서 (도움이된다면)?

감사합니다.

답변

2

면책 조항 : 저는 이것을 훨씬 더 깨끗한 약속으로 해결할 것입니다. 궁금하신 분은 물어 보시면 답변을 제공해 드리겠습니다.

하지만, 당신이 무엇을 요구, 여기에 있습니다 :

router.get('/', function (req, res, next) { 

    var userId='1'; 

    var returnHtml = ''; 

    client.hgetall('user:'+userId, function(err,objects){ 
    returnHtml+=utils.inspect(objects); 
    client.hgetall('user_lastlogged:'+userId, function(err,objects){ 
     returnHtml+=utils.inspect(objects); 
     client.hgetall('user_favourites:'+userId, function(err,objects){ 
      returnHtml+=utils.inspect(objects); 
      res.send(returnHtml); 
     });   
    }); 
    }); 
}); 

업데이트 : 블루 버드 대답은 다른 게시물에 제공되었다. 나는 Q 사용자가 너무 Q와 이런 식으로 그것을 할 것입니다 : 당신이 사용하는 경우 많이 발생합니다 그래서 노드에서

var q = require('q'); 

var promiseHGetAll = function(key, htmlFragment){ //making a promise version for the function call. 

    if(!htmlFragment) htmlFragment=""; //optional argument, of course 

    var deferred = q.defer(); //a deferred is an object that has a promise in it. and some methods 
    client.hgetall(key,deferred.makeNodeResolver()); 
    //makeNodeResolver is for node methods that have 
    //function(err,result) call back. if the function has an error, 
    //the promise will be rejected and err will be passed to it. 
    // if there is no err, the promise will be resolved and result 
    // will be passed to it. 

    return deferred.promise.then(function(objects){ 
     //the first argument to then() is a function that is called 
     //if the promise succeeds. in this case, this is objects returned 
     // from Redis. 
     return htmlFragment + utils.inpect(objects); 
     // this function can return a promise or a value. 
     // in this case it is returning a value, which will be 
     // received by the next .then() in the chain. 
    }); 
} 

router.get('/', function(req,res){ 
    var userId = "1"; 
    promiseGetAll("user"+userId).then(function(htmlFragment){ 
     //this is called when the promise is resolved, and the 
     //utils.inspect(objects) is called and the return value is 
     //supplied to this then() 
     return promiseGetAll("user_lastlogged"+userId, htmlFragment); 
     //.then() functions can return a promise. in this case, the 
     // next .then will be called when this promise is resolved or rejected. 

    }).then(function(withUserLastLogged){ 

     return promiseGetAll("user_favourites"+userId,withUserLastLogged); 

    }).then(function(returnHTML){ 

     res.send(returnHTML); 

    }).catch(function(error){ 
     //this will be called if there is an error in the node calls, 
     // or any of the previous .then() calls throws an exception, 
     // or returns a rejected promise. it is a sugar syntax for 
     // .then(null, function(err){..}) 
     res.status(503).send(error); 
    }).done(); //throw an error if somehow something was escaped us. shouldn't happen because of catch, but force of habit. 
}) 
+0

예, 감사합니다 당신이 약속에 조금 정교한한다면, 나는 매우 감사 할 것입니다. :) –

3

대부분의 코드는, 비동기입니다.

기본적으로 체인 작업에 콜백을 사용해야합니다. 이 콜백 지옥의 약간의 당신이 볼 수 있듯이

var redis = require("redis"); 
var client = redis.createClient(); 

router.get('/', function (req, res, next) { 

    var userId='1'; 

    var returnHtml = ''; 

    client.hgetall('user:'+userId, function(err,objects){ 
    returnHtml+=utils.inspect(objects); 
    client.hgetall('user_lastlogged:'+userId, function(err,objects){ 
     returnHtml+=utils.inspect(objects); 
     client.hgetall('user_favourites:'+userId, function(err,objects){ 
     returnHtml+=utils.inspect(objects); 
     res.send(returnHtml); 
     }); 
    }); 
    }); 
}); 

, 당신은 더 읽을 수 있도록 호출을 promisify하는 https://github.com/NodeRedis/node_redis#user-content-promises으로 보일 수 있습니다. 같은 블루 버드

그것이 보일 수 있습니다 :

var bluebird = require('bluebird'); 
var redis = require('redis'); 
bluebird.promisifyAll(redis.RedisClient.prototype); 
bluebird.promisifyAll(redis.Multi.prototype); 

var client = redis.createClient(); 

router.get('/', function (req, res, next) { 

    var userId='1'; 

    var returnHtml = ''; 

    client.hgetallAsync('user:'+userId) 
    .then(function(objects){ 
    returnHtml += utils.inspect(objects); 
    return client.hgetallAsync('user_lastlogged:'+userId); 
    }) 
    .then(function(objects){ 
    returnHtml+=utils.inspect(objects); 
    return client.hgetallAsync('user_favourites:'+userId); 
    }) 
    .then(function(objects){ 
    returnHtml+=utils.inspect(objects); 
    res.send(returnHtml); 
    }) 
    .catch(function(err){ 
    //manage error 
    }); 

}); 
+0

감사합니다 보리스! –

관련 문제