Setidaknya ada dua masalah dalam kode ini:
-
yang pertama terkait dengan manajemen penutupan Javascript. Tubuh loop tidak membuat ruang lingkup. Dengan Javascript, cakupan variabel berada pada level fungsi, bukan level blok. Anda perlu memperkenalkan beberapa fungsi dalam loop itu sendiri untuk menegakkan pembuatan penutupan yang tepat. Informasi lebih lanjut di sini.
-
yang kedua adalah kondisi balapan antara perintah yang ada dan yang ditetapkan. Jika Anda memiliki beberapa koneksi Redis yang berjalan dan mengatur perintah pada kunci yang sama, Anda mungkin akan mengalami beberapa jenis konflik. Alih-alih menggunakan yang ada dan yang disetel, Anda harus menggunakan setnx yang melakukan pemeriksaan dan penyetelan dalam satu operasi atom.
Mempertimbangkan contoh kedua Anda, masalah penutupan telah diperbaiki dengan menggunakan forEach, tetapi Anda masih menghasilkan semua operasi get sebelum operasi yang disetel karena sifat bahasa yang asinkron.
Jika Anda benar-benar ingin mengurutkan semua operasi get and set (yang akan jauh lebih lambat btw), maka Anda dapat menggunakan sedikit pemrograman fungsional untuk mengimplementasikan loop menggunakan rekursi.
Contoh :
Program ini:
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)
menampilkan:
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
Perhatikan bahwa kondisi balapan masih ada dalam contoh ini. Anda seharusnya menggunakan setnx untuk mengimplementasikan operasi pemeriksaan dan penyetelan semacam ini.