丢失variables范围

所以,一旦我解决了我之前遇到的问题,我试图在login时从数据库中获取玩家帐户的X,Y坐标(所以它们不是放在1,1上,而是放在最后一个跟踪的坐标上)

经过一番debugging,我来到这个:

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(); }); }); 

这是整个function – 以防万一缺less一个范围。 但这里是麻烦的线路:

 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将解决这个问题的function触发之前,我的查询完成,但我猜不是。

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

注意:下一步是将我的疑虑从函数中分离出来,所以请忽略我在比赛中像接力棒那样绕过conmysql 。 谢谢!

       

网上收集的解决方案 "丢失variables范围"

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

 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(); }); }); 

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

因为JavaScript I / O是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; }); 

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

所以xy不会在你创buildref对象的时候被设置并返回这个对象。

尝试这样的事情:

 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); }); }); 

另外因为你的整个函数是asynchronous的,所以你必须使用callback或者返回一个promise,在这个promise中你可以访问ref Object。