对于循环内部节点请求,不按预期执行

时间:2014-10-21 17:10:04

标签: node.js express mongoose

我是节点的新手,我正在努力解决这里发生的事情:

app.get('/set_users/', function(req, res){
    var users = [
        {
            email: "tom@gmail.com",
        },
        {
            email: "jon@gmail.com",
        }
    ];


    for(i=0; i<users.length; i++){

        console.log("Logging index");
        console.log(i);

        User.findOne({email: users[i].email}, function(err, user){

            console.log("Printing index");
            console.log(i);

            if (err){
                //Do something with error;
            }

            if (user) {
                //User already exists - do something
            }
            else{
                //Add new user
            }
    }
});

我希望console.log语句的输出为:

logging index
0
logging index
1
Printing index
0
Printing index
1

然而我得到了:

logging index
0
logging index
1
Printing index
2
Printing index
2

有人想知道这里发生了什么吗?

3 个答案:

答案 0 :(得分:1)

使用此答案的帮助:https://stackoverflow.com/a/16879859/1493564

我想出的答案是:

app.get('/set_users/', function(req, res){
    var users = [
        {
            email: "tom@gmail.com",
         },
         {
             email: "jon@gmail.com",
         }
     ];


    for(i=0; i<users.length; i++){

        console.log("Logging index");
        console.log(i);
        (function(i){
             User.findOne({email: users[i].email}, function(err, user){

                console.log("Printing index");
                console.log(i);

                if (err){
                    //Do something with error;
                }

                if (user) {
                    //User already exists - do something
                }
                else{
                    //Add new user
                }
         })(i)
    }
});

不确定是否有人知道更好的解决方案?

答案 1 :(得分:1)

您需要确保回调中使用的变量不会被其他迭代更改:

for(i=0; i<users.length; i++){

    var currentUserIndex = i;

    User.findOne({email: users[i].email}, function(err, user){

        console.log("Printing index");
        console.log(currentUserIndex);
    });
}

答案 2 :(得分:0)

您正在将一个回调函数传递给User.findOne,该函数在for循环完成后被触发(值为2)。 User.findOne是一个异步函数,因此它会在完成后触发回调。