Redis
 sql >> Database >  >> NoSQL >> Redis

nodejs, redis. controlla se le chiavi esistono e creane di nuove in caso contrario

Ci sono almeno due problemi in questo codice:

  • il primo è legato alla gestione della chiusura Javascript. Il corpo di un ciclo non crea un ambito. Con Javascript, l'ambito delle variabili è a livello di funzione, non a livello di blocco. È necessario introdurre alcune funzioni nel ciclo stesso per imporre la creazione di una chiusura adeguata. Maggiori informazioni qui.

  • il secondo è una race condition tra i comandi exist e set. Se esistono diverse connessioni Redis in esecuzione e si impostano comandi sugli stessi tasti, è probabile che si verifichi un qualche tipo di conflitto. Invece di utilizzare esiste e set, dovresti usare setnx che esegue il controllo e imposta in un'operazione atomica.

Considerando il tuo secondo esempio, il problema di chiusura è stato risolto utilizzando forEach, ma continui a generare tutte le operazioni get prima delle operazioni set a causa della natura asincrona del linguaggio.

Se vuoi davvero mettere in sequenza tutte le tue operazioni get e set (che saranno molto più lente tra l'altro), puoi usare un po' di programmazione funzionale per implementare il ciclo usando la ricorsione.

Esempio :

Questo programma:

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)

visualizza:

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

Si noti che la race condition è ancora presente in questo esempio. Dovresti usare setnx per implementare questo tipo di operazioni di controllo e impostazione.