我正在尝试使用promises来调用getLoginState然后存储该值,以便稍后使用它。
我想知道为什么在下面的代码块中,在getLoginState方法之前调用q.fcall(getLoginState)中的.then?
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();
};
答案 0 :(得分:3)
promises中的流控制就像在同步代码中一样:
return
关键字。throw
关键字。承诺的工作方式 - 是等待他们。 nfcall
在NodeJS样式上调用" errback"打回来。为了使代码正常工作,您需要从getLoginState返回,然后不使用nfcall
,因为该方法已经返回了一个承诺:
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
};
然后在上面的部分:
// 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
我想强调一下这可以写得更好,没有充分的理由在这里筑巢而不是链,并且连接应该在一个承诺中完成 - 上面的代码是最接近的你的代码有效。