【问题标题】:JS Promises with MySQL to create org structure from flat tableJS Promises with MySQL 从平面表创建组织结构
【发布时间】:2018-06-22 13:12:18
【问题描述】:

我这几天一直在尝试完成这项工作,但似乎无法让它发挥作用。

我有一个如下所示的 MySQL 表:

empName empID empManagerID -------------------------------------------------- ---------- 亚历克斯经理 125354 987654 简·多伊 223535 125354 弗洛伊德·古兹曼 654354 125354 伊尔玛·弗莱彻 325150 212335 托尼·科普兰 456842 325150 本杰明普拉特 231543 325150 卡桑德拉·加德纳 656560 325150 弗雷德里克·布罗格登 783487 239873 Deangelo Glandon 823402 783487 杰拉尔丁·布拉尔 *230123 783487 杰娜·莱蒙德 182739 783487 夏季维尔茨 849734 783487 克拉丽莎谢弗 983787 783487 坦纳·博尔特 345623 *230123 Charlesetta Debolt 923476 230123 迈克尔·古安 456782 230123 多米尼克·皮拉诺 956235 125354 Shavonne Ovellette 108934 125354

我希望能够通过提供经理的员工 ID 作为起点,找到向特定经理 ID 报告的所有人员的姓名。

例如:

Select * from tableName where empManagerID = '125354';

这应该返回:

简·多伊 223535 125354 弗洛伊德·古兹曼 654354 125354 多米尼克·皮拉诺 956235 125354 夏冯娜·欧维莱特 108934 125354

然后,我需要获取结果中的每一个 empID,并使用 empID 作为 empManagerID 创建多个查询,以查找所有向结果中的人报告(如果有的话)的人。

这需要在最终查询基本上为空之前进行。

在我参加的课程的助教的帮助下,我能够做到这一点:

函数 getEmployees(employerID) { 常量查询 = ` 选择 empName、empID、empManagerID 从我的表 WHERE empManagerID = ${employerID} `; 返回新的承诺((解决,拒绝)=> { con.query(query, (err, rows, fields) => { 返回解析(行); }); }); } 获取雇员(125354) .then((员工) => { // 将返回的结果推送到某种数组中。 const empPromises = employees.map((e) => { 返回 getEmployees(e.empID) }); 返回 Promise.all(empPromises); }) // fs.writeFile 输出到reports.json 文件以供将来参考。

上面的代码有效,但似乎没有递归提取结果,我不知道为什么。实际表有数千行,有多个级别的employee => manager => sr manager 关系

如果我尝试将另一个 .then() 与另一个对 getEmployees 的调用链接起来,它只会返回一堆承诺 - 而不是结果。但是,如果我 console.log (rows),我可以看到结果。

我对 JS 还很陌生,还在学习……但我就是想不通这个。

任何帮助将不胜感激。

【问题讨论】:

  • This should return ...是的,是吗?如果不是,那么数据不是您所说的那样-另外,我不明白为什么,从@ 987654323@ 的managerid 开始时会出现任何递归,因为@ 987654324@ 管理的那些员工都没有有人“在”他们
  • 是的,你是对的,在我分享的样本数据中,没有人低于 125354...但是在实际表(大约 100,000 行)中,有员工低于 125354,其中一些员工下有人员,依此类推。

标签: javascript mysql promise


【解决方案1】:

对于递归,您需要一个调用自身(或以某种方式导致自身被调用)的函数。

并且在每次迭代中,您需要:

  • 查找给定员工的下属(部分或无)
  • 返回下属列表以及每个下属的下属

由于递归,在下一个级别执行相同的操作,最终导致原始调用者最终被传递给所有下属、下属的下属、下属的下属的下属等的列表。

// modified data, expressed as a javascript object-literal
var allEmployees = [
    { 'empName':'Alex Manager',       'empID':'125354', 'empManagerID':'987654' },
    { 'empName':'Jane Doe',           'empID':'223535', 'empManagerID':'125354' },
    { 'empName':'Floyd Guzman',       'empID':'654354', 'empManagerID':'125354' },
    { 'empName':'Irma Fletcher',      'empID':'325150', 'empManagerID':'125354' },
    { 'empName':'Toni Copeland',      'empID':'456842', 'empManagerID':'325150' },
    { 'empName':'Benjamin Pratt',     'empID':'231543', 'empManagerID':'325150' },
    { 'empName':'Cassandra Gardner',  'empID':'656560', 'empManagerID':'325150' },
    { 'empName':'Fredrick Brogdon',   'empID':'783487', 'empManagerID':'239873' },
    { 'empName':'Deangelo Glandon',   'empID':'823402', 'empManagerID':'783487' },
    { 'empName':'Geraldine Brar',     'empID':'230123', 'empManagerID':'231543' },
    { 'empName':'Jayna Lemmond',      'empID':'182739', 'empManagerID':'783487' },
    { 'empName':'Summer Wirtz',       'empID':'849734', 'empManagerID':'783487' },
    { 'empName':'Claretha Sheffer',   'empID':'983787', 'empManagerID':'783487' },
    { 'empName':'Tanna Boelter',      'empID':'345623', 'empManagerID':'230123' },
    { 'empName':'Charlesetta Debolt', 'empID':'923476', 'empManagerID':'230123' },
    { 'empName':'Michael Gouin',      'empID':'456782', 'empManagerID':'230123' },
    { 'empName':'Dominick Piraino',   'empID':'956235', 'empManagerID':'125354' },
    { 'empName':'Shavonne Ovellette', 'empID':'108934', 'empManagerID':'125354' }
];

// simple filter in place of SQL
function getEmployeesOf(employerID) {
    return Promise.resolve(allEmployees.filter(emp => emp.empManagerID === employerID));
}

// recursive function (it calls itself)
function drillDown(employerID) {
    return getEmployeesOf(employerID).then(employees => {
        let promises = employees.map(emp => drillDown(emp.empID));
        return Promise.all(promises).then(emps => employees.concat(...emps)); // spreading here avoids the need to flatmap later.
    });
}

drillDown('125354').then(results => {
    console.log('Results: ', results);
});

DEMO 使用上面修改过的数据,这应该会给出 12 名员工的列表。

为了比较,如果一切都是同步的,这就是这两个函数的样子:

function getEmployeesOf(employerID) {
    return allEmployees.filter(emp => emp.empManagerID === employerID);
}

function drillDown(employerID) {
    let employees = getEmployeesOf(employerID);
    return employees.concat(...employees.map(emp => drillDown(emp.empID)));
}

DEMO 修改后的数据相同

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-09
    相关资源
    最近更新 更多