【问题标题】:Return value of FindOne mongoose nodejsFindOne mongoose nodejs 的返回值
【发布时间】:2016-10-08 20:34:02
【问题描述】:

好吧,在用 50 种不同的方式尝试了这段代码之后,我正在敲我的脑袋。

所以我有一个 2v2 的示例游戏,在每个游戏模式中,玩家都被引用到用户和他们的用户名。

现在在游戏中,我想从这些用户那里获取评分并相应地更新它们,这必须同时发生。

我似乎无法处理我的用户对象(来自长期使用 Java,因此其中一些直接使用没有意义)。

如果可能的话,我想扩展它,所以一大堆嵌套的代码不是我想要的。

废话不多说:

游戏架构:

var gameSchema = mongoose.Schema({
    teamA_player1:      { type: String, ref: "userModel", required: true},
    teamA_player2:      { type: String, ref: "userModel", required: true},
    teamB_player1:      { type: String, ref: "userModel", required: true},
    teamB_player2:      { type: String, ref: "userModel", required: true},
    teamA_score:        { type: Number, required: true},
    teamB_score:        { type: Number, required: true}, 
    author:             { type: String, ref: "userModel", required: true},
    verification:       [{ type: String, ref: "userModel", required: true}],
    verified:           { type: Boolean},
    timestamp:          { type: Date}
});

用户架构:

var userSchema = mongoose.Schema({
    username:       { type: String, required: true, unique: true},
    password:       { type: String, required: true},
    firstName:      { type: String},
    lastName:       { type: String},
    about:          { type: String},
    email:          { type: String},
    clubs:          { type: [{type: ObjectId, ref: "clubModel"}]},
    games:          { type: [{type: ObjectId, ref: "gameModel"}]}, 
    rating:         { type: Number}
});

我的游戏控制器中的代码存在问题:

updateRating = function(game){

    // The following code blob doesn't work and calling a_1.rating just gives Nan / undefined.
    var a_1 = users.findOne({username: game.teamA_player1});
    var a_2 = users.findOne({username: game.teamA_player2});
    var b_1 = users.findOne({username: game.teamB_player1});
    var b_2 = users.findOne({username: game.teamB_player2});

    var a_rating_old = (a_1.rating+a_2.rating)/2;
    var b_rating_old = (b_1.rating+b_2.rating)/2;

    var a_rating_new = 0;
    var b_rating_new = 0;

    if(game.teamA_score>game.teamB_score){
        a_rating_new = ratingChange(a_rating_old, b_rating_old, true);
        b_rating_new = ratingChange(b_rating_old, a_rating_old, false);
    }else{
        a_rating_new = ratingChange(a_rating_old, b_rating_old, false);
        b_rating_new = ratingChange(b_rating_old, a_rating_old, true);
    }

    var a_rating_change = a_rating_new - a_rating_old;
    var b_rating_change = b_rating_new - b_rating_old;

    a_1.rating += Math.round(a_rating_change * (a_rating_old/a_1.rating));
    a_2.rating += Math.round(a_rating_change * (a_rating_old/a_2.rating));
    b_1.rating += Math.round(b_rating_change * (b_rating_old/b_1.rating));
    b_2.rating += Math.round(b_rating_change * (b_rating_old/b_2.rating));

    a_1.save();
    a_2.save();
    b_1.save();
    b_2.save();

}

所以基本上我想知道在这里获取我的用户的正确方法是什么,提取他们的评分,更新它,然后用新的评分保存用户(游戏本身不会发生任何变化)。

代码也都可以在这里找到:https://github.com/mathieudevos/pinkiponki

【问题讨论】:

    标签: node.js mongodb mongoose mongoose-schema


    【解决方案1】:

    好吧,我在尝试这个问题时似乎有很多错误的想法。

    主要问题是我没有考虑所有数据库查询都运行异步的事实,这造成了巨大的麻烦。

    现在选项 A 是将它们全部嵌套在一起,这最终会产生一个巨大的代码块/意大利面条,而不是真正的粉丝。特别是因为如果我想继续在这个应用程序上写作,这不是很好。

    所以对于选项 b,安装模块 deasync 并只需 #DealWithIt

    代码如下:

    var done = 0;
    
    var a_1;
    var a_2;
    var b_1;
    var b_2;
    
    users.findOne({username: game.teamA_player1}, function(err, usera1){
        if(usera1)
            a_1 = usera1.rating;
        done += 1;
    });
    users.findOne({username: game.teamA_player2}, function(err, usera2){
        if(usera2)
            a_2 = usera2.rating;
        done += 1;
    });
    users.findOne({username: game.teamB_player1}, function(err, userb1){
        if(userb1)
            b_1 = userb1.rating;
        done += 1;
    });
    users.findOne({username: game.teamB_player2}, function(err, userb2){
        if(userb2)
            b_2 = userb2.rating;
        done += 1;
    });
    
    //Keep looping on deasync until we find all 4
    require('deasync').loopWhile(function(){return (done!=4);});
    
    if(a_1 == undefined || a_2 == undefined || b_1 == undefined || b_2 == undefined){
        // could not find a user probably
        log('Value undefined, error');
        return;
    }
    

    【讨论】:

      【解决方案2】:

      因此,假设您已经在该 user 变量中需要模型,那么您做错的事情是您将该函数分配给一个变量(例如 a_1),而实际上您需要传递一个回调函数,然后将该回调接收的用户分配给该变量。

      类似这样的:

      user.findOne({username: game.teamA_player1}, function(err, user){
        if(err) throw err;
        a_1 = user;
      });
      

      我建议您将需要模型的变量名称从用户更改为用户。

      你可以看到我传递的回调函数有一个错误对象和一个用户对象,最后一个是你的信息存储的地方,来自数据库的对象,所以你应该将它的值分配给你想要的变量,在本例中为 a_1。

      如果成功了请告诉我!

      【讨论】:

      • 这将我的 a_1 限制在函数内部,使我无法在函数外部使用它(错误,用户){ //code and var goes here }。我想将它显示给我的 updateRating 函数,在那里处理评级并在那里更新它们。
      • 你需要在外面声明变量。
      猜你喜欢
      • 2018-08-07
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 2018-07-07
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多