문제

So, once I sorted out my promise issues with my previous problems, I tried to grab the Player accounts X,Y coordinates from the database upon login (so that they are not placed on 1,1, but instead on their last tracked coordinates)

After some debugging, I came to this:

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

That's the whole function -- just in case some scope is missing. But here is the trouble lines:

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

I was under the impression Promise would solve this issue of functions triggering before my query is complete, but I guess not.

Why is my function returning before the X,Y variables are set?

Note: the NEXT step is to separate my concerns from the functions, so please ignore that I am passing around con and mysql like a baton at a race. Thanks!

도움이 되었습니까?

해결책 2

Promises don't change the language, it's just a library. It cannot change how function returning works. However, do you want something like this:

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

다른 팁

Why is my function returning before the X,Y variables are set?

Because JavaScript I/O is asynchronous.

If you want to wait for two promises - you need to hook on the promise's completion. Luckily, promises make this super simple for you with Promise.all and 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;
});

The functions getX and getY are asynchronous functions. Promise solves the issue of nesting anonymous functions, but it don't make the functions synchronous and blocking.

So x and y are not set at the moment you create the ref object and return this object.

Try something like this:

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

Also because your whole function is asynchronous, you have to work with an callback or return a promise, in which you have access to ref Object.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top