在下面的代码中,我有一个无限循环,我不知道为什么会发生。我最好的猜测是因为里面的函数是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');
}
});
});
};
该函数接收一个 userId (User.findOne()
用于查找用户,如果没有具有该 id 的用户,则拒绝承诺)并创建一个unique该用户的随机令牌(randomGenerator
) ,将其添加到保存在 MongoDB 中的用户实体并将其返回给调用者。
(NOTE有一些反对票说这个问题与this one https://stackoverflow.com/questions/7268579/for-loop-and-async-callback-in-node-js这并不是因为我的代码中已经有一个闭包,但它仍然不起作用。这个问题更多的是关于如何将循环变量绑定到闭包)
你是对的,你不能像你试图做的那样循环。
JavaScript 是单线程的。只要主线程在你的循环中while(loop)
声明,没有其他东西有机会运行。如果你的主线程本身正在改变,这一切都可以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');
}
});
});
};
我应该注意到你的错误处理不完整User.findOne()
手术。
仅供参考,不断查询直到得到的整个逻辑result.length === 0
只是看起来很奇怪。这个逻辑看起来很奇怪,而且闻起来像“在紧密循环中轮询数据库”,这通常是一件性能非常差的事情。我怀疑,如果我们在更高层次上理解整个问题,就会有更有效的方法来解决这个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)