パスワードがユーザーのパスワード履歴にあるかどうかを評価する関数に従う必要があります。コードは次のとおりです。
isPasswordInPwdHistory : function(redisClient, userId, encPassword, cb) {
var key = 'user:' + userId + ':pwdhistory';
redisClient.llen(key, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else {
var numPwds = reply;
var match = false;
var funcError;
for (i=0; i <= numPwds - 1; i++) {
var error;
var pwdValue;
redisClient.lindex(key, i, function(err, reply) {
if (err) {
console.log('lindex err = ' + err);
error = err;
}
else {
console.log('lindex reply = ' + reply);
console.log('lindex encPassword = ' + encPassword);
console.log('lindex (encPassword === reply) = ' + (encPassword === reply));
pwdValue = reply;
}
});
console.log('for-loop error = ' + error);
console.log('for-loop pwdValue = ' + pwdValue);
console.log('for-loop (encPassword === pwdValue) = ' + (encPassword === pwdValue));
if (error) {
funcError = error;
break;
}
else if (encPassword === pwdValue) {
console.log('passwords match');
match = true;
break;
}
}
console.log('funcError = ' + funcError);
console.log('match = ' + match);
if (funcError) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else
cb(match);
}
});
}
コンソール出力は次のとおりです。
for-loop error = undefined
for-loop pwdValue = undefined
for-loop (encPassword === pwdValue) = false
funcError = undefined
match = false
isPasswordInPwdHistory = false
lindex reply = 5f4f68ed57af9cb064217e7c28124d9b
lindex encPassword = 5f4f68ed57af9cb064217e7c28124d9b
lindex (encPassword === reply) = true
redisClient.lindex()呼び出しのスコープを離れると、値が失われます。forループで評価するためにこれらの値を渡すにはどうすればよいですか?
アップデート
redisClient.lindex()コールバックが発行されたときに、新しいパスワード(encPassword)とインデックスiの既存のパスワードの一致を処理するために、コードを少しリファクタリングしました。
isPasswordInPwdHistory : function(redisClient, userId, encPassword, cb) {
var status = new Object();
var key = 'user:' + userId + ':pwdhistory';
redisClient.llen(key, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else {
var numPwds = reply;
var loopCt = 0;
for (i=0; i <= numPwds - 1; i++) {
loopCt++;
redisClient.lindex(key, i, function(err, reply) {
if (err) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, err, null, null, null);
cb(status);
}
else if (encPassword === reply) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, null, 0, null, true);
cb(status);
}
else if (loopCt === numPwds && encPassword !== reply) {
status.results = [ ];
xutils.addStatusResultsItem(status.results, null, 0, null, false);
cb(status);
}
});
}
}
});
}
残念ながら、encPassword === replyがtrueであり、cb(status)を発行しても、呼び出し元にはstatus===undefinedが表示されます。cb(status)を発行した後、forループを完全に終了するにはどうすればよいですか?