Node.js和for循环行为很奇怪

时间:2015-03-04 13:12:24

标签: javascript node.js mongodb

我正在为我的实习工作,他们在后端使用node.js和mongoDB。这个设置目前确实不能很好地工作,因为我们实际上有关系数据,而mongoDB实际上并不是最好的。

我的问题是,我必须从数据库中获取一些需要在两个表上“加入”的数据。 MongoDB不允许这样做,所以我试图手动完成。 我必须找到一个演出,并为每个工作类型(JobTypeLine)演出,找到有关受邀工作人员的信息。 RolodexMembersInterested是一个包含ID的数组,允许我们在RolodexMember“表”中查找员工信息。

json结构如下所示:

千兆:

    {
        _id: {type: Schema.ObjectId},
        CreatedAt: {type: Date, default: Date.now()},
        EventName: {type: String, required: true},
        Headline: {type: String, required: true},
        Date: {type: Date, required: false},
        EndDate: {type: Date, required: false},
        Address: {type: String, required: false},
        Description: {type: String, required: true},
        CompanyName: {type: String, required: true},
        CompanyID: {type: String, required: true},
        Exposed: {type: Boolean, default: false},
        HashTags: {type: []},
        JobTypeLine: {type: [
            {
                JobType: {type: String, required: true},
                Briefing: {type: String, required: false},
                Quantity: {type: Number, required: true},
                StartTime: {type: String, required: true},
                EndTime: {type: String, required: true},
                NumberOfHours: {type: String, required: false},
                HourlySalary: {type: Number, required: false},
                RolodexMembersInvited: {type: [], default: []},
                RolodexMembersAssigned: {type: [], default: []},
                RolodexMembersInterested: {type: [], default: []}
            }
        ]},
    },

RolodexMember:

    {
        _id:{type:Schema.ObjectId},
        companyId: {type: String, required: true},
        userId: {type: String, required: false},
        userEmail: {type: String, required: true},
        comment: {type: String, required: false},
        payRate: {type: Number, required: false},
        name: {type: String, required: false},
        phone: {type: String, required: false},
        pictureUrl: {type: String, required: false},
        isHot: {type: Boolean, required: false},
        isInPaySystem: {type: Boolean, required: false},
        numberOfPreviousGigs: {type: Number, required: true, default: 0},
        previousGigs: [],
        otherAttributes: [
            {
                attributeName: {type: String, required: false },
                attributeValue: {type: String, required: false }
            }
        ],
    })

所以我写了一个方法来“模拟”我的联接:

    exports.getMembersInvitedToGig = function(req,res) {

        var jobTypes = [];
        var rolodexInvited = [];
        gigsModel.findOne({_id: req.body.gigId}, function(err, gig) {
            if(err) {
                console.log(err);
                res.send(404, "Couldn't find the gig with id: " + req.body.gigId);
            } else {
                for(var i=0;i<gig.JobTypeLine.length;i++){
                    rolodexInvited = [];
                    for(var j=0;j<gig.JobTypeLine[i].RolodexMembersInvited.length;j++) {
                        var userId = gig.JobTypeLine[i].RolodexMembersInvited[j];
                        getUserData(userId, function(data,success) {
                            if (success) {
                                rolodexInvited[j] = data;
                            }
                        });
                    }
                    jobTypes[i] = rolodexInvited;
                }
                res.send(200,jobTypes);
            }
        });
    }

    function getUserData (userId, callback) {
        var RolodexItem = mongoose.model('RolodexItems');
        RolodexItem.findOne({ _id: userId }, function (err, doc) {
            if (err) {
                console.log("There was an error in finding the rolodex item: " + err);
            } else {
                    callback(doc,true);
            }
        });
    }

我的问题是方法返回和空数组填充其他空数组(尽可能多的我有jobTypes)。我知道getUserData函数工作正常并找到合适的人员信息等问题所在,似乎节点不等待数据在for(j)循环内返回并继续(最终结束获取)到res.send(200,jobTypes),而jobTypes实际上仍然是空的。我已经尝试在getUserData中添加一个回调来解决这个问题,但它没有改变任何东西。

(现在我知道使用关系数据库可以一起解决问题,但我真的没有发言权,所以我必须让它按原样运行)。可能还有一些非常糟糕的做法,因为我只是基于以前由其他人制作的功能,而且我注意到他们并不擅长它。我之前从未使用过node.js,所以我没有时间看一些正确的做法/等等。 (随意指出任何写得不好的东西,我很乐意学习“好”的方法)

1 个答案:

答案 0 :(得分:0)

问题是你的getUserData函数是异步的(因为findOne是异步的)。所以你的for循环不会等待你的getUserData函数完成。 您应该使用异步库(查看每个函数):https://github.com/caolan/async

相关问题