Ari*_*deh 6 javascript node.js promise
在下面的代码中,我有一个无限循环,我不知道它为什么会发生.我最好的猜测是因为里面的函数是async循环不等待它,所以循环永远不会停止.解决这个问题的最佳方法是什么?
var generateToken = function(userId) {
return new Promise(function(resolve, reject) {
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) {
loop = false;
reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined) {
user.tokens = [];
}
user.tokens.push(e);
loop = false;
resolve();
}
}
});
})(token);
}
} else {
return reject('UserNotFound');
}
});
});
};
Run Code Online (Sandbox Code Playgroud)
此函数接收userId(User.findOne()用于查找用户,如果没有具有该id的用户,拒绝承诺)并为该用户创建唯一的随机令牌(randomGenerator),将其添加到MongoDB中保存的用户实体中将其返回给调用者.
(注:有一些下降票说这个问题是一样的这一个这是不是因为我已经在我的代码有一个关闭,它仍然无法正常工作.这个问题是更多关于如何将循环变量来关闭绑定)
你是不对的,你不能像你想做的那样循环.
Javascript是单线程的.因此,只要主线程在您的while(loop)语句中循环,NOTHING就有机会运行.如果您的主线程本身正在更改loop变量,那么这一切都会好的,但这并不是正在发生的事情.相反,您正在尝试更改loop异步响应中的变量,但由于主线程正在循环,因此永远不会处理异步响应,因此您的loop变量永远不会被更改,从而导致无效的无限循环.
要修复,您必须更改为不同的循环结构.常见的设计模式是创建一个本地函数,其中包含您想要重复的代码.然后,运行异步操作,如果在异步结果处理程序中,您决定要重复操作,则只需从其中再次调用本地函数.因为结果是异步的,所以堆栈已经展开,这在技术上并不是堆栈构建的递归.它只是启动了该函数的另一个迭代.
我对你的代码中的逻辑感到有点困惑(那里有零注释来解释它)所以我不完全确定我是否正确,但这里是一般的想法:
var generateToken = function(userId) {
return new Promise(function(resolve, reject) {
User.findOne({userId: userId}, function(err, user) {
function find() {
var token = Common.randomGenerator(20);
User.find({tokens: e}, function(err, result) {
if (err) {
reject('Error querying the database');
} else {
if (result.length === 0) {
if (user.tokens === undefined) {
user.tokens = [];
}
user.tokens.push(e);
resolve();
} else {
// do another find until we don't find a token
find();
}
}
});
}
if (user !== null) {
find();
} else {
reject('UserNotFound');
}
});
});
};
Run Code Online (Sandbox Code Playgroud)
我应该注意你在操作上有不完整的错误处理User.findOne().
仅供参考,不断查询直到你得到的整个逻辑result.length === 0似乎很奇怪.逻辑似乎很奇怪,它闻起来像"在紧密循环中轮询数据库",这通常是一个非常糟糕的表现.我怀疑如果我们在更高层次上理解整体问题,有更有效的方法来解决这个问题.