NodeJS / MySQL /承诺麻烦

时间:2017-05-09 14:59:18

标签: mysql node.js promise

我在全球范围内对NodeJS和JS都很陌生,我在通过MySQL查询设置和对象属性时遇到了麻烦。

我使用Promise来避免错误的异步效果,但显然我做错了,我的Agent Obejct的属性永远不会更新。

以下是代码:

user$

我用这种方式调用方法:

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

}

你能帮我解决这个问题吗?

由于

2 个答案:

答案 0 :(得分:0)

主要问题是在承诺解决之前正在执行console.log。在"内写一个console.log然后"子句将告诉你时间。

最终将解决或拒绝承诺,但没有人在等待setAgentCountry。

答案 1 :(得分:0)

这里有几个要点:

  1. 承诺必须始终(1)已解决或(2)被拒绝。您的错误案例会将其记录到控制台而不会调用reject(),因此当它出现错误时,它会永远陷入承诺中。

  2. 为什么要命名变量promise,与库名Promise相同?

  3. 我认为你会发现将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} );
                    }
                }
            );
        });
    };
    
  4. 那么你可以像这样使用它:

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

    请注意,我没有测试过类代码,但一般的想法应该足以回答你的问题了。