Redis
 sql >> Base de données >  >> NoSQL >> Redis

nodejs, redis. vérifier si les clés existent et créer de nouvelles sinon

Il y a au moins deux problèmes dans ce code :

  • le premier est lié à la gestion des fermetures Javascript. Le corps d'une boucle ne crée pas de portée. Avec Javascript, la portée des variables est au niveau de la fonction, pas au niveau du bloc. Vous devez introduire une fonction dans la boucle elle-même pour imposer la création d'une fermeture appropriée. Plus d'informations ici.

  • le second est une condition de concurrence entre les commandes exists et set. Si vous avez plusieurs connexions Redis en cours d'exécution et que vous définissez des commandes sur les mêmes clés, vous aurez probablement une sorte de conflit. Au lieu d'utiliser exists et set, vous devez utiliser setnx qui effectue la vérification et la définition en une seule opération atomique.

Considérant votre deuxième exemple, le problème de fermeture a été résolu en utilisant forEach, mais vous générez toujours toutes les opérations get avant les opérations set en raison de la nature asynchrone du langage.

Si vous voulez vraiment séquencer toutes vos opérations get et set (ce qui sera beaucoup plus lent), vous pouvez utiliser un peu de programmation fonctionnelle pour implémenter la boucle en utilisant la récursivité.

Exemple :

Ce programme :

var redis = require('redis')
var rc = redis.createClient(6379, 'localhost');

var tags = [
  "apple",
  "tiger",
  "mouse",
  "apple",
  "apple",
  "apple",
  "tiger",
  "mouse",
  "mouse",
];

var count = 0;

function loop(tags) {
  function rec_loop(tags,i) {
     if ( i >= tags.length )
        return
     rc.get("tag:"+tags[i],function(err,rr) {
        console.log("get tag "+tags[i]+" result code "+rr);
        if ( rr == null ) {
           rc.set("tag:"+tags[i],"info",function(err,rr) {
              count++;
              console.log('set tag '+tags[i]+' '+rr+' objects count '+count);
              rec_loop(tags,++i)
           })
        } else
          rec_loop(tags,++i)
     })
  }
  rec_loop(tags,0)
}

loop(tags)

affiche :

get tag apple result code null
set tag apple OK objects count 1
get tag tiger result code null
set tag tiger OK objects count 2
get tag mouse result code null
set tag mouse OK objects count 3
get tag apple result code info
get tag apple result code info
get tag apple result code info
get tag tiger result code info
get tag mouse result code info
get tag mouse result code info

Notez que la condition de concurrence est toujours présente dans cet exemple. Vous êtes censé utiliser setnx pour implémenter ce type d'opérations de vérification et de définition.