我对全球 NodeJS 和 JS 很陌生,在通过 MySQL 查询设置和对象属性时遇到了麻烦。
我正在使用 Promise 来避免不良的异步效果,但显然我做错了,我的代理 Obejct 的属性永远不会更新。
这是代码:
class Agent {
constructor(agentId, agentName, agentCountry) {
this.agentId = agentId;
this.agentName = agentName;
this.agentCountry = agentCountry;
}
setAgentCountry () {
var promise = function(agentID) {
return new Promise(function(resolve, reject) {
var query = "SELECT c.CountryID, c.CountryName FROM AgentCountry ac, Country c WHERE ac.AgentID = '" + agentID + "' AND ac.CountryID = c.CountryID";
connection.query(query, function(err, results) {
if (!err) {
resolve(results);
} else {
console.log('Error while performing Query.');
}
});
});
}
promise(this.agentID).then(function(data) {
var string = JSON.stringify(data);
var json = JSON.parse(string);
//the agent property is never updated !!
this.agentCountry = json;
}.bind(this), function(err) {
console.log(err);
});
}
}
我这样称呼该方法:
var agent = new Agent(1,"John Doe", "France");
console.log(agent.agentCountry); //Displays "France"
agent.setAgentCountry();
console.log(agent.agentCountry); //Did not display the table of countries it should
你能帮我这个吗?
谢谢
主要问题是console.log
是在解决承诺之前执行的。在"then"子句中写一个console.log
将向你显示时间。
承诺最终将被解决或拒绝,但没有人在等待setAgentCountry。
这里有几个程序点:
-
承诺必须始终是 (1( 已解决或 (2( 拒绝。 您的错误案例将其记录到控制台而不调用 reject((,因此当它出错时,它会永远陷入承诺的困境。
-
为什么要命名一个变量,
promise
,与库相同,Promise
? -
我想你会发现将 mysql_conn.query(( 回调包装到 promise(( 中更加模块化:
const mysql_conn = mysql.createConnection({ host: mysql_conf.host, user: mysql_conf.user, password: mysql_conf.password }); mysql_conn.queryPromiser = function(sql, args) { return new Promise(function(resolve, reject) { mysql_conn.query( sql, args, function(err, results, fields) { if (err) { reject(err); } else { resolve( {"results": results, "fields": fields} ); } } ); }); };
然后你可以像这样使用它:
class Agent {
constructor(agentId, agentName) {
this.agentId = agentId;
this.agentName = agentName;
this.agentCountry = null;
}
configureCountryPromiser() {
var sql = "SELECT country FROM agent_countries WHERE agent_id = ?";
var args = [ this.agentId ];
var that = this;
return mysql_conn.queryPromiser(sql, args)
.then(function(data) {
if (data.results.length) {
that.agentCountry = data.results[0].country;
} else {
// handle case where agent_id is not found in agent_countries
}
});
}
};
agent_instance = new Agent(1, "Benoit Duprat");
agent_instance.configureCountryPromiser()
.then(function() {
console.log("agent country configured to ", agent_instance.agentCountry);
}).catch(console.error);
请注意,我没有测试过类代码,但总体思路应该足以回答您的问题。