Node.js链接与MySQL的循环承诺

我正在尝试将一个非关系数据库变成一个关系数据库。 所以我从没有唯一ID的数据开始。

我需要从一个SQL调用循环中通过这些行得到结果,并且对于每一个,使用第一个结果的一部分执行SQL SELECT,然后使用下一个结果执行另一个SQLselect,然后使用来自第一个最后的查询。

我正在使用Node.js和ES6承诺保持一切顺序,但我似乎失去了一些东西。 实际上,我正在尝试执行额外的SQL调用,并且在第三个查询中也使用了这个结果,但是我正在简化它,只是让一个调用进入另一个调用。

也许一些代码将帮助显示我正在尝试做什么。

这是我的查询类返回承诺:

var mysql = require('mysql'); class Database { constructor() { this.connection = mysql.createConnection({ host: "localhost", user: "root", password: "root", database: "pressfile" }); } query(sql, args) { return new Promise((resolve, reject) => { this.connection.query(sql, args, (err, result, fields) => { if (err) return reject(err); resolve (result); }); }); } close() { return new Promise((resolve, reject) => { this.connection.end(err => { if (err) return reject (err); resolve(); }); }); } } 

这几乎是从一个教程网站被盗,这部分似乎工作得很好。 接下来是循环和多个查询:

 var contactId; var address1; var orgName; var database = new Database(); database.query("SELECT * FROM contact") .then( result => { for (var i = 0; i < result.length; i++) { contactId = result[i].contactId; orgName = result[i].org; var sql2 = "SELECT * FROM organization WHERE (name = \"" + orgName + "\")"; console.log(sql2); database.query(sql2) .then(result2 => { console.log(result2); var orgId = result2[0].organizationId; var sql3 = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")"; console.log(sql3); return ""; //database.query(sql3); }).then( result3 => { console.log(result3); }); } }).catch((err) => { console.log(err); databse.close(); }); 

我知道这是最终解体,但我不想要执行INSERT查询,直到我知道我可以正确的。 现在在控制台,我得到一个有效的组织对象,其次是:

 `INSERT INTO contact_organization (contactId, organizationId) VALUES (17848, 29)' 

17848是在for循环中返回的最后一个contactId。 如何获取在第二个查询之前分配的contactId。 我知道我没有做这个asynchronous的东西。

尝试这样的事情。 快速解决scheme (未testing)。

 const selectOrg = (result) => { contactId = result[i].contactId; orgName = result[i].org; var sql = "SELECT * FROM organization WHERE (name = \"" + orgName + "\")"; return database.query(sql); }; const insertOrg = (result) => { var orgId = result[0].organizationId; var sql = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")"; return database.query(sql); }; database.query("SELECT * FROM contact") .then(result => { const promises = []; for (var i = 0; i < result.length; i++) { promises << selectOrg(result) .then(insertOrg); } return Promise.all(promises); }) .then(allResults => { console.log(allResults); }) .catch((err) => { databse.close(); }); 

我find了一个方法来做到这一点,但它是一种俗气。 我在SQL查询中包含了contactId作为常量来获取组织,所以我可以将值传递给.then,保持一切顺序。

我的sql2语句变成:

 var sql2 = "SELECT *, " + contactId + " AS contactId FROM organization WHERE (name = \"" + orgName + "\")"; 

然后,当这个查询返回时,我可以从结果[0] .contactId,从我得到organizationId相同的结果只是拉出正确的contactId出。

这是最后的代码:

 database.query("SELECT * FROM contact") .then( result => { for (var i = 0; i < result.length; i++) { var contactId = result[i].contactId; var orgName = result[i].org; var sql2 = "SELECT *, " + contactId + " AS contactId FROM organization WHERE (name = \"" + orgName + "\")"; database.query(sql2) .then(result2 => { var orgId = result2[0].organizationId; var contactId = result2[0].contactId; var sql3 = "INSERT INTO contact_organization (contactId, organizationId) VALUES (" + contactId + ", " + orgId + ")"; console.log(sql3); return database.query(sql3); }).then( result3 => { console.log(result3); }); } }).catch((err) => { console.log(err); databse.close(); }); 

console.log(result3)返回一堆这些:

 OkPacket { fieldCount: 0, affectedRows: 1, insertId: 0, serverStatus: 2, warningCount: 0, message: '', protocol41: true, changedRows: 0 } 

我为第一个查询返回的每个联系人行插入一个contact_organization。