В този код има поне два проблема:
-
първият е свързан с управлението на затваряне на Javascript. Тялото на цикъл не създава обхват. С Javascript обхватът на променливите е на ниво функция, а не на ниво блок. Трябва да въведете някаква функция в самия цикъл, за да наложите създаването на правилно затваряне. Повече информация тук.
-
вторият е условие за състезание между командите съществуване и задаване. Ако имате няколко изпълнявани връзки с Redis и зададете команди на едни и същи клавиши, вероятно ще имате някакъв вид конфликти. Вместо да използвате exists и set, трябва да използвате setnx, които извършват проверка и set в една атомна операция.
Имайки предвид втория ви пример, проблемът със затварянето е отстранен с помощта на forEach, но вие все още генерирате всички операции get преди операциите set поради асинхронния характер на езика.
Ако наистина искате да подредите всичките си операции get и set (които между другото ще бъдат много по-бавни), тогава можете да използвате малко функционално програмиране, за да приложите цикъла с помощта на рекурсия.
Пример :
Тази програма:
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)
показва:
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
Имайте предвид, че състоянието на състезанието все още присъства в този пример. Трябва да използвате setnx, за да приложите този вид операции за проверка и задаване.