2012-01-11 3 views
3

J'utilise node_redis pour fournir un service de noeud avec une représentation JSON des objets que je reçois de redis. Je pense que c'est probablement assez élémentaire pour beaucoup d'entre vous, mais je suis perplexe. J'arrive au point où j'envoie ma réponse avant J'ai été à travers tous mes hashes et les ai stockés. Voici le coffeescript:Comment convertir les hachages redis en JSON?

objects = [] 
    client.keys 'objects*', (err,keys) -> 
     for key in keys 
     client.hgetall key, (err,obj) -> 
      objects.push obj 
    response.end JSON.stringify objects 

et JavaScript généré:

 objects= []; 
     client.keys('objects*', function(err, keys) { 
     var key, _i, _len, _results; 
     _results = []; 
     for (_i = 0, _len = keys.length; _i < _len; _i++) { 
      key = keys[_i]; 
      _results.push(client.hgetall(key, function(err, obj) { 
      return objects.push(obj); 
      })); 
     } 
     return _results; 
     }); 
     return response.end(JSON.stringify(objects)); 

Je ne sais pas comment mettre mon code en vacances alors qu'il attend la substance intérieure pour terminer. Je pense qu'il y a un moyen de le gérer, mais je ne vois rien. Merci à tous.

Répondre

2

Vous êtes donc en train d'itérer sur n clés, puis de retourner JSON.stringify (objets) après avoir appelé client.keys (qui appellera à son tour client.hgetall pour chaque clé?), Mais vous retournerez ensuite response.end (JSON.stringify (objects)) après l'appel à client.keys.

Le problème est simple: vous devez afficher une réponse dans la fonction qui ajoute le résultat de hgetkeys, mais seulement une fois que vous avez vu toutes les réponses de hgetkeys.

Je ne suis pas un mordu coffeescript, mais voici une version en javascript qui devrait fonctionner:

objects= []; 
    client.keys('objects*', function(err, keys) { 
    var key, _i, _len, seen; 
    seen = 0; 
    for (_i = 0, _len = keys.length; _i < _len; _i++) { 
     key = keys[_i]; 
     client.hgetall(key, function(err, obj) { 
     objects.push(obj); 
     seen++; 
     if (seen == len) { 
      return response.end(JSON.stringify(objects)); 
     } 
     }); 
    } 
    }); 

je devrais noter, un inconvénient est que si vous ne recevez jamais une réponse de l'un des hgetall demandes, cela expirera et vous n'émettrez jamais de réponse. Il peut être préférable de modifier la façon dont vous stockez vos hachages pour pouvoir obtenir toutes les valeurs en même temps, ou avoir une fonction que vous appelez après un certain temps pour émettre une réponse afin que votre client n'attende pas pour toujours.

Puis-je vous demander pourquoi vous avez choisi d'écrire ceci dans coffeescript? Cela ressemble à un énorme casse-tête d'écrire un nœud quand il traverse une couche de traduction comme ça.

+1

Merci ... cela * va * résoudre mon problème. Je me suis dit qu'il me manquait un motif qui retarderait l'exécution jusqu'à ce que tout soit terminé, mais je me suis trompé à plusieurs reprises auparavant. En ce qui concerne "changer la façon dont vous stockez les hachages", je suis toujours ouvert aux suggestions. Je suis fraîchement sorti de relationnelDB-land et je suis habitué à saisir facilement un tas d '«objets» basés sur des critères arbitraires. – CircusNinja

+0

J'ai passé un temps looooong avec redis en essayant d'abord de comprendre comment structurer mes données afin qu'il soit plus facile d'interroger. Je me suis retrouvé à écrire beaucoup de code de nœud avec des fonctions asynchrones "internes" et "externes" et ensuite à rendre une réponse à la fin. En fin de compte, j'ai modifié mon schéma pour pouvoir extraire des données, puis les filtrer. Cela dépend toutefois de votre cas d'utilisation, il y a des raisons légitimes de le faire de cette façon. – tjarratt