【问题标题】:NodeJS/MySQL/Promises TroublesNodeJS/MySQL/Promises 问题
【发布时间】:2017-10-07 23:15:36
【问题描述】:

我对全局的 NodeJS 和 JS 还是很陌生,在通过 MySQL 查询设置对象属性时遇到了麻烦。

我正在使用 Promise 来避免糟糕的异步效果,但显然我做错了,我的 Agent 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

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

谢谢

【问题讨论】:

标签: mysql node.js promise


【解决方案1】:

主要问题是console.log 在promise 被解决之前被执行。在“then”子句中写入console.log 将显示时间。

promise 最终会被解决或拒绝,但没有人在等待 setAgentCountry。

【讨论】:

  • 是的,我认为您已经找到了问题所在,但我需要访问我正在调用该方法的更新后的 Country 属性。 console.log 只是一个占位符,我应该返回一个 Agent。我该如何管理?
【解决方案2】:

这里有几个顺序:

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

那么你可以像这样使用它:

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

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

【讨论】:

    猜你喜欢
    • 2016-02-27
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 2018-09-08
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多