2014-03-28 66 views
2

因此,一旦我解决了我以前遇到的问题时的承诺问题,我试图在登录时从数据库中获取玩家帐户的X,Y坐标(这样它们不会放在1,1上,而是在他们的最后跟踪坐标)失去可变范围

一些调试后,我来到了这一点:

var x; //note I also tried to define these directly above the getX/Y() and it didn't work 
var y; 
return con.getConnectionAsync().then(function(connection) { 
    return connection.queryAsync('SELECT password,id FROM player WHERE name='+mysql.escape(req.body.user)) 
     .spread(function(rows, fields) { 
     if (hash.verify(req.body.pass,rows[0].password)) { 
      req.session.loggedIn = true; 
      req.session.user = rows[0].id; 
      getX(rows[0].id,con,mysql).then(function(data) { 
       x = data; 
      }); 
      getY(rows[0].id,con,mysql).then(function(data) { 
       y = data; 
      }); 
      console.log(x,y,"line77"); 
      ref = new P(rows[0].id,x,y); 
      res.send({ 
       "msg":"You have logged in!", 
       "flag":false, 
       "title":": Logged In" 
      }); 
      return ref; 
     } else { 
      res.send({ 
       "msg":"Your username and or password was incorrect.", 
       "flag":true, 
       "title":": Login Failed" 
      }); 
     } 
    }).finally(function() { 
     connection.release(); 
    }); 
}); 

这就是全部的功能 - 只是在某些范围缺失的情况下。但这里是麻烦线:

getX(rows[0].id,con,mysql).then(function(data) { 
    x = data; //x logs the return 7 from the db 
}); 
getY(rows[0].id,con,mysql).then(function(data) { 
    y = data; //y logs 45 from the db 
}); 
console.log(x,y,"line77"); //logs "undefined undefined line77" 
ref = new P(rows[0].id,x,y); 

我的印象Promise下就可以解决的触发之前我查询功能齐全这个问题,但我想不会。

为什么我的函数在X,Y变量设置之前返回?

注意:下一步是将我的担忧与功能区分开来,所以请忽略我在比赛中接力棒conmysql。谢谢!

回答

1

承诺不改变语言,它只是一个库。它不能改变函数返回的工作方式。但是,你想要这样的东西:

return con.getConnectionAsync().then(function(connection) { 
    var x; 
    var y; 
    return connection.queryAsync('SELECT password,id FROM player WHERE name='+mysql.escape(req.body.user)) 
     .spread(function(rows, fields) { 
     if (hash.verify(req.body.pass,rows[0].password)) { 
      req.session.loggedIn = true; 
      req.session.user = rows[0].id; 
      ref = new P(rows[0].id,x,y); 
      res.send({ 
       "msg":"You have logged in!", 
       "flag":false, 
       "title":": Logged In" 
      }); 
      return Promise.all([ 
       getX(rows[0].id,con,mysql), 
       getY(rows[0].id,con,mysql) 
      ]).then(function(xy) { 
       x = xy[0]; 
       y = xy[1]; 
      }).return(ref); 
     } else { 
      // Should probably throw a LoginError here or something 
      // because if we get here, we don't define x and y 
      // and that will require an annoying check later 
      res.send({ 
       "msg":"Your username and or password was incorrect.", 
       "flag":true, 
       "title":": Login Failed" 
      }); 
     } 
    }).then(function() { 
     // If the login succeeded x and y are defined here. 
     // However, in the else branch you don't define 
     // x and y so you will need to check here. 
     // Had you thrown an error in the else branch 
     // you would know that x and y are always defined here. 
     use(x, y); 
    }).finally(function() { 
     connection.release(); 
    }); 
}); 
0

函数getXgetY是异步函数。 Promise解决了嵌套匿名函数的问题,但它不会使函数同步和阻塞。

因此,xy不会在您创建ref对象时设置并返回此对象。

尝试这样:

getX(rows[0].id,con,mysql).then(function(data) { 
    x = data; //x logs the return 7 from the db 
    getY(rows[0].id,con,mysql).then(function(data) { 
     y = data; //y logs 45 from the db 
     console.log(x,y,"line77"); //logs "undefined undefined line77" 
     ref = new P(rows[0].id,x,y); 
    }); 
}); 

也因为你的整个功能是异步的,你有一个回调的工作或返回一个承诺,在其中您可以访问ref对象。

+0

请考虑阅读http://stackoverflow.com/questions/22539815/arent-promises-just-callbacks –

2

为什么我的函数在X,Y变量设置之前返回?

Because JavaScript I/O is asynchronous

如果您想等待两个承诺 - 您需要挂钩承诺的完成。幸运的是,承诺通过Promise.allPromise.spread使您对此非常简单。

Promise.all(getX(rows[0].id,con,mysql),getY(rows[0].id,con,mysql)).spread(function(x,y){ 
    console.log(x,y);//should work; 
});