如何在使用NodeJS并保存到MongoDB时同步多个RESTFul请求?

时间:2013-02-13 22:47:08

标签: javascript node.js mongodb mongoose synchronous

我一直在尝试使用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");
        }
    });
}

2 个答案:

答案 0 :(得分:2)

您应该考虑在架构中将user_name设置为唯一。即使同时请求设置相同的用户名,这也将确保user_name保持唯一。

答案 1 :(得分:1)

是的,发生这种情况的原因与您怀疑的一样,因为多个请求可以同时执行代码,因此User.fineOne可以多次返回false。顺便说一下,这也可能发生在其他堆栈中,甚至是每个请求使用一个线程的堆栈。

要解决这个问题,您需要一种方法来控制当时只有一个用户正在处理,您可以通过将所有registerUser请求添加到队列然后逐个将它们从队列中拉出来完成此操作调用res.Send只有在队列处理后才会发送。

或者,也许您可​​以保留本地用户名数组,并且每次有新请求进入时都会检查数组是否已存在。如果它没有将它添加到数组并进行处理。如果它在数组中,则发送响应" User exists"。然后,一旦成功创建了用户,就可以从该阵列中删除它。 (我还没有想到这一点到100%,但我认为它也应该有效。)