Why is this nested promise.then executed before the promise's method?

I am trying to use promises to call getLoginState and then store that value so I can use it later.

I am wondering why in the following codeblock, the .then inside of q.fcall(getLoginState) is called before the getLoginState method?

var mysql = require('mysql');
var q = require('q');

var login = "tyler";
var connection = mysql.createConnection({
    host : 'localhost',
    user: 'root',
    password: 'root',
    port: '3306',
    database: 'root'
});

var gotLoginState;
var state;

connection.connect(function(err) {
    if(err != null){
        console.log("connection err: "+err);
    }

    q.nfcall(connection.query.bind(connection),"SELECT id, password, salt, gender, banned, gm, pin, pic, characterslots, tos FROM accounts WHERE name = ?",[login])
        .then(function (results) {
          console.log("select: "+results[0][0]);
//        }).then(q.fcall(getLoginState), function () {
            q.fcall(getLoginState)
                .then(function() {
                    console.log("gotLoginState: " + state);
                }).catch(function (error){
                   console.log("error in inner thing");
            }).done();
        }).catch(function (error) {
            console.error("promise error: "+error);
        })
        .done();
});

var accId = 1;
var getLoginState = function() {
    q.nfcall(connection.query.bind(connection), "SELECT loggedin, lastlogin, UNIX_TIMESTAMP(birthday) as birthday FROM accounts WHERE id = ?", [accId])
        .then(function (results) {
            state = results[0][0].loggedin;
        }).catch(function (error) {
            console.log("error in chaining: "+error);
        }).done();
};

The flow control in promises works like in synchronous code:

  • To return you use the return keyword.
  • To signal an error you use t he throw keyword.

The way promises work - is by waiting for them. nfcall is called on a NodeJS style "errback" callback. In order for your code to work you need to return from getLoginState, and then not use nfcall since the method already returns a promise:

var getLoginState = function() { // this should be nodeify probably
    return q.nfcall(...) // note the `return` statement here
        .then(function (results) {
            state = results[0][0].loggedin; // do not mutate state like this
        }).catch(function (error) {         // instead use return values
            console.log("error in chaining: "+error); // don't suppress errors
                                                      // logging is not enough
        }); // don't do `.done` if you want to chain to it
};

And then in the above part:

// don't use the `.connect` callback, promisify it
q.nfcall(...) // promisify that method _once_ in your real code
.then(function (results) {
   console.log("select: "+results[0][0]); // why just the log?
   return getLoginState() // note this is a regular function call
            .then(function() { // also note the `return`
                console.log("gotLoginState: " + state);
            }).catch(function (error){
               console.log("error in inner thing");
    }); // no done here, since we chain to it
}).catch(function (error) {
    console.error("promise error: "+error);
}).done(); // you only need one `.done` at the end, and only in old
           // promise libraries

I'd like to emphasize that this could could be written better, there is no good reason to nest here rather than chain, and the connecting should be done in a promise - the above code is just the closest thing to your code that works.