我一直在尝试使用NodeJS实现RESTFul API,并使用Mongoose(MongoDB)作为数据库后端。
以下示例代码在同时发送请求时使用相同的用户名注册多个用户,这不是我想要的。虽然我试图添加支票!
我知道这是因为NodeJS的异步性质,但我找不到正确执行此操作的方法。看起来“findOne”方法会立即返回,导致registerUser返回,然后处理另一个请求。
顺便说一句,我不想检查具有单独API函数的现有用户,我需要在注册阶段进行检查。有没有办法做到这一点?
Controller.prototype.registerUser = function (req, res) {
Users.findOne({'user_name': req.body.user_name}, function(err, user) {
if(!user) {
new User({user_name: req.body.user_name}).save(function(err) {
if(!err) {
res.send("User saved");
} else {
res.send("DB Error: Could not save user!");
}
});
} else {
res.send("User exists");
}
});
}
答案 0 :(得分:2)
您应该考虑在架构中将user_name设置为唯一。即使同时请求设置相同的用户名,这也将确保user_name保持唯一。
答案 1 :(得分:1)
是的,发生这种情况的原因与您怀疑的一样,因为多个请求可以同时执行代码,因此User.fineOne可以多次返回false。顺便说一下,这也可能发生在其他堆栈中,甚至是每个请求使用一个线程的堆栈。
要解决这个问题,您需要一种方法来控制当时只有一个用户正在处理,您可以通过将所有registerUser请求添加到队列然后逐个将它们从队列中拉出来完成此操作调用res.Send只有在队列处理后才会发送。
或者,也许您可以保留本地用户名数组,并且每次有新请求进入时都会检查数组是否已存在。如果它没有将它添加到数组并进行处理。如果它在数组中,则发送响应" User exists"。然后,一旦成功创建了用户,就可以从该阵列中删除它。 (我还没有想到这一点到100%,但我认为它也应该有效。)