Return hgetall list from redis in nodejs

ぃ、小莉子 提交于 2020-11-27 02:49:28

问题


I'm trying to return a json object so that I can pass it back before a page is rendered to populate a list. My problem is that I can't figure out how to pass the object data out from the hgetall callback function. Here is my example with comments on what I'm missing:

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

function createMobs() {

    var mobObject = {
        name: "Globlin",
        hp: 12,
        level: 1
    };
    client.hmset("monsterlist", "mobs", JSON.stringify(mobObject));

    var myMobs = function(object) {
        return object;
    };

    var getMobs = function(callback) {   
      client.hgetall("monsterlist", function(err, object) {
        callback(object);
      });    
    };

    // This is returning undefined instead of my mob
    console.log("mobs: ", getMobs(myMobs));

    // Goal is to return moblist
    // return getMobs(myMobs);

}

exports.createMobs = createMobs;

回答1:


The short answer is that you're not thinking asynchronously. Because you're using asynchronous functions in your function, your function must also be asynchronous.

Since you didn't post the rest of your code, here's the basic idea:

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

function createMobs(callback) {
    var mobObject = { name: 'Goblin' };

    client.hmset('monsterlist', 'mobs', JSON.stringify(mobObject), function(err) {
        // Now that we're in here, assuming no error, the set has went through.

        client.hgetall('monsterlist', function(err, object) {
            // We've got our object!

            callback(object);
        });

        // There is no way to run code right here and have it access the object variable, as it would run right away, and redis hasn't had time to send you the data yet. Your myMobs function wouldn't work either, because it is returning a totally different function.
    });
};

app.get('/create', function(req, res) {
    createMobs(function(object) {
        res.render('mobs.jade', {
            mobs: object
        });
    });
});

Hopefully that helps clear things up.




回答2:


The only way to deal with hgetall returning value are by Promises.

get all function:

 async hashget(tag) {
        return new Promise((resolve, reject) => {
          redis.createClient({ port: portnumber, host: config.redis.host 
           }).hgetall(tag, (err, object) => {
            if (err) {
              reject(err);
            } else {
              resolve(Object.keys(object));
            }
          });
        });
      }

and handle it in the through the promise as

const result = await this.redis.hashget('asize').then((result) => {
        return result;
 });
return result;



回答3:


I also encountered similar issue wherein I would need the result of hgetall back the function calling it. Here is how I got it working on my end.

export const test = async (hashId) => {
  // reachedLimit will have value after the hgetall result on the `monitorLimit` function
  const reachedLimit = await monitorLimit(hashId);
}

export const monitorLimit = (hashId) => {
  let reachedLimit = false;
  let attempts = 0;

  return new Promise((resolve, reject) => redisDB.hgetall(hashId, (err, result) => {
    if (err) {
      // TODO reject logic here...
    }

    if (result) {
      attempts = Number(result.tries);

      if (attempts === 3) {
        reachedLimit = true;
        resolve({ reachedLimit });
      }
    }

    attempts += 1;

    redisDB.hmset(hashId, ['tries', attempts], (createErr) => {
      if (createErr) {
        // TODO reject logic here...
      }
    });

    // expire in 3 minutes
    redisDB.expire(hashId, 180);
    resolve({ reachedLimit });
  }));
};



回答4:


my solution for this error SyntaxError: Unexpected token o in JSON at position 1

res.send(Object.values(JSON.parse(JSON.stringify(object))))



来源:https://stackoverflow.com/questions/22108216/return-hgetall-list-from-redis-in-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!