JS承诺用MySQL从平面表创建组织结构

时间:2018-01-13 04:48:58

标签: javascript mysql promise

我一直试图让这项工作工作几天,似乎无法让它发挥作用。

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

    empName               empID             empManagerID
    ------------------------------------------------------------
    Alex Manager          125354            987654
    Jane Doe              223535            125354
    Floyd Guzman          654354            125354

    Irma Fletcher         325150            212335
    Toni Copeland         456842            325150
    Benjamin Pratt        231543            325150
    Cassandra Gardner     656560            325150


    Fredrick Brogdon      783487            239873
    Deangelo Glandon      823402            783487
    Geraldine Brar        *230123           783487
    Jayna Lemmond         182739            783487
    Summer Wirtz          849734            783487
    Claretha Sheffer      983787            783487


    Tanna Boelter         345623            *230123
    Charlesetta Debolt    923476            230123
    Michael Gouin         456782            230123
    Dominick Piraino      956235            125354
    Shavonne Ovellette    108934            125354

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

例如:

Select * from tableName where empManagerID = '125354';

这应该返回:

Jane Doe              223535            125354
Floyd Guzman          654354            125354
Dominick Piraino      956235            125354
Shavonne Ovellette    108934            125354

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

这需要在最终查询基本为空之前发生。

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

    function getEmployees(employerID) {
        const query = `
            SELECT empName, empID, empManagerID
            FROM myTable
            WHERE empManagerID = ${employerID}
        `;

      return new Promise((resolve, reject) => {
            con.query(query, (err, rows, fields) => {
                return resolve(rows);
        });
      });
    }

    getEmployees(125354)
        .then((employees) => {
            // push returned results to an array of some sort. 

            const empPromises = employees.map((e) =>  { 
                return  getEmployees(e.empID)           
            });
        return Promise.all(empPromises);
        })

        // fs.writeFile out to a reports.json file for future reference. 

上面的代码有效,但似乎没有递归地提取结果,我无法弄清楚原因。实际的表有数千行,其中有许多级别的employees => manager => sr经理关系

如果我尝试使用另一个getEmployees调用链接另一个.then(),它只返回一堆承诺 - 而不是结果。但是,如果我是console.log(行),我可以看到结果。

我对JS很新,还在学习......但我无法想象这一点。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

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

在每次迭代中,您需要:

  • 找到给定员工的下属(部分或无人)
  • 返回下属列表加上每个下属的下属

由于递归,在下一级执行同样的操作,最终在原始调用者中最终传递所有下属,下属的下属,下属的下属的下属等的列表。

// 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