我使用以下代码为用户生成唯一令牌。用户数据存储在MongoDB中,因此我使用promise来处理与db的异步通信。在WebStorm中,我收到了这个警告:Mutable variable is accessible from closure with promise and loop.
我知道有关于此事的帖子,但我的情况更复杂。我知道我甚至不需要担心它,因为我只使用token
的最后一个值,但我想以正确的方式解决这个问题?
var generateToken = function(userId) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
var loop = true;
while (loop) {
var token = Common.randomGenerator(20);
User.find({tokens: token}, function(err, result) {
if (err) {
loop = false;
return Promise.reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined){
user.tokens.push(token);
}
loop = false;
return Promise.resolve(token);
}
}
});
}
} else {
return Promise.reject('UserNotFound');
}
});
};
我提出了以下解决方案,这是正确的吗?
var generateToken = function(userId) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
var loop = true;
while (loop) {
var token = Common.randomGenerator(20);
(function(e){
User.find({tokens: e}, function(err, result) {
if (err) {
return Promise.reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined){
user.tokens = [];
}
user.tokens.push(e)
return Promise.resolve(e);
}
}
});
})(token);
}
} else {
return Promise.reject('UserNotFound');
}
});
};
注意正如@Alex Nikulin建议的那样,我在发回承诺的结果之前将loop
翻到false
。但它仍然是一个无限循环,因为它没有进入User.find({tokens: e})....
答案 0 :(得分:0)
你的问题是,return语句在函数内,而不在循环内。你的循环是无限的。我已经解密了你的代码。或者当你解决/拒绝承诺时,简单地使循环为false。此外,我的代码将等待用户的每个答案,错误将消失。你的变量包裹函数是正确的(function(e){})(token)
。
var generateToken = function(userId) {
return new Promise(function(resolve, reject) {
User.findOne({userId: userId}, function(err, user) {
if (user !== null) {
userTokenIterator(user,resolve, reject);
} else {
reject('UserNotFound');
}
});
});
};
var addTokenToUser = function(token,user){
return new Promise(function(resolve, reject) {
User.find({tokens: token}, function(err, result) {
if (err) {
reject('Error querying the database');
} else {
var result = result.length === 0;
if (result) {
if(!user.tokens) {
user.tokens = []
}
user.tokens.push(token);
}
resolve(result);
}
});
});
};
var userTokenIterator = function (user, resolve, reject){
var token = Common.randomGenerator(20);
addTokenToUser(token, user).then(function(result){
if(result) {
resolve(token);
}else{
userTokenIterator(user,resolve, reject)
}
},function(error){
reject(error);
});
};