2017-05-09 19 views
0

NodeJSとJSの世界的な新機能ですが、MySQLのクエリを通じてObject Propertyを設定しているうちに困ります。NodeJS/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 

あなたはこれで私を助けてもらえますか?

おかげ

+0

https://www.npmjs.com/package/promise-mysql – bxN5

答えて

0

主な問題は、約束が解決される前にconsole.logが実行されていることです。 "then"句の中にconsole.logを書くとタイミングが表示されます。

約束は最終的に解決されるか拒否されますが、誰もsetAgentCountryを待っていません。

+0

はい、あなたは問題を理解したと思いますが、メソッドを呼び出す更新されたCountryプロパティにアクセスする必要があります。 console.logは単にプレースホルダに過ぎず、代わりにエージェントを返すべきです。それをどうすれば管理できますか? –

0

は、ここでは注文のいくつかのポイントがあります。

  1. 約束は常には、いずれかでなければなりません(1)解決または(2)拒否しました。エラーが発生した場合は、reject()を呼び出さずにコンソールにログを記録します。エラーが発生した場合、永久にlimboを約束します。

  2. なぜ変数名をpromise、ライブラリと同じ名前にしますかPromise

  3. 私はあなただけの約束()にmysql_conn.query()コールバックをラップすることがよりモジュールを見つけるだろうと思い:

    :あなたはそうのようにそれを使用することができます

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

私はクラスコードをテストしていませんが、一般的な考え方で十分であることにご注意ください。