[英]Mutable variable is accessible from closure with promise and loop
I use the following code to generate a unique token for a user. 我使用以下代码为用户生成唯一的令牌。 Data for users is stored on MongoDB so I use promise to handle asynchronous talking to the db.
用户的数据存储在MongoDB上,因此我使用promise处理与数据库的异步对话。 In WebStorm I receive this warning :
Mutable variable is accessible from closure with promise and loop.
在WebStorm中,我收到此警告:
Mutable variable is accessible from closure with promise and loop.
and I know there have been posts on SO about this thing, but I my case is more complicated. 而且我知道有关于此事的帖子,但是我的情况更复杂。 I know I may not even need to worry about it as I only use the last value of
token
but what I want to solve this issue in a correct way ? 我知道我什至不必担心它,因为我仅使用
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');
}
});
};
I came up with the following solution , is it correct ? 我想出了以下解决方案,对吗?
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');
}
});
};
NOTE As @Alex Nikulin suggested , I flipped loop
to false
before sending back the result of the promise. 注意:正如@Alex Nikulin所建议的那样,我在将承诺结果发送回之前将
loop
翻转为false
。 But still it's an infinite loop as it doesn't go into the User.find({tokens: e})....
但这仍然是一个无限循环,因为它没有进入
User.find({tokens: e})....
Your problem is that, return statement is within function, not within loop.Your loop is infinite. 您的问题是,return语句在函数内,而不在循环内。您的循环是无限的。 I has decomposited your code.Or simply make loop false, when you resolve/reject promise.
我已经分解了您的代码,或者在您解析/拒绝promise时简单地将loop设为false。 Also my code will wait each answer from User, and error will gone.
同样,我的代码将等待用户的每个答案,错误将消失。 And your variant with wrap function is correct
(function(e){})(token)
. 并且带有wrap函数的变量是正确的
(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);
});
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.