所以,一旦我解决了我之前的问题的承诺问题,我试图在登录时从数据库中获取玩家账号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变量之前返回?
注意:NEXT步骤是将我的关注点与功能区分开来,所以请忽略我在比赛中像接力棒一样传递con
和mysql
。谢谢!
答案 0 :(得分:2)
为什么我的函数在设置X,Y变量之前返回?
Because JavaScript I/O is asynchronous。
如果你想等待两个承诺 - 你需要挂钩承诺的完成。幸运的是,承诺通过Promise.all
和Promise.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;
});
答案 1 :(得分: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();
});
});
答案 2 :(得分:0)
函数getX
和getY
是异步函数。 Promise解决了嵌套匿名函数的问题,但它不会使函数同步和阻塞。
因此,在您创建x
对象并返回此对象时,y
和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
对象。