Javascript 承诺链陷入了一个循环

Javascript 承诺链陷入了一个循环,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我想调用一个函数,该函数返回一个承诺两次,但当该函数最终永远调用自己时,有时调用外部函数,有时调用内部函数。这是一个有问题的函数,retrieveDependency()返回一个承诺 function renderDiffProject(projName, branchName, res, org=undefined){ let newScan; let oldScan; retrieveDependency(projName, branchName, 1, org).then

我想调用一个函数,该函数返回一个承诺两次,但当该函数最终永远调用自己时,有时调用外部函数,有时调用内部函数。这是一个有问题的函数,
retrieveDependency()
返回一个承诺

function renderDiffProject(projName, branchName, res, org=undefined){
   let newScan;
   let oldScan;
   retrieveDependency(projName, branchName, 1, org).then(result => { 
      newScan = result;
      console.log("inside retrieve deps");
      return retrieveDependency(projName, branchName, 2, org);
   })
   .then(result => {
      oldScan = result;
      console.log("successfully got dependencies")
      res.render('project', {projname: projName, branch: branchName, proj:JSON.stringify(newScan), oldproj:JSON.stringify(oldScan)})
   })
}
这是
retrieveDependence()的代码

数据库。查询
定义如下:

class Database {
  constructor() {
      this.connection = mysql.createConnection({
        host: 'azure.com',
        user: 'admin-portal-mysql',
        password: '2341234#1',
        database: 'yatadb'
      });
  }
  query( sql, args ) {
      return new Promise( ( resolve, reject ) => {
          this.connection.query( sql, args, ( err, rows ) => {
              if ( err )
                  return reject( err );
              resolve( rows );
          } );
      } );
  }

我们可以使用async/await简化renderDiffProject:

async function renderDiffProject(projName, branchName, res, org=undefined){
    const newScan = await retrieveDependency(projName, branchName, 1, org);
    const oldScan = await retrieveDependency(projName, branchName, 2, org);
    console.log("successfully got dependencies")
    res.render('project', {projname: projName, branch: branchName, proj: JSON.stringify(newScan), oldproj: JSON.stringify(oldScan)})
}
我们还可以简化检索依赖性:

async function retrieveDependency(projname, branch, n, org=undefined) {
    // combine both queries
    const sql = `
        SELECT * FROM branch_scan 
        WHERE fossa_scan_id = (
            SELECT (scanid) FROM foozie 
            WHERE 
                project = ${projname} 
                AND branch = ${branch} 
                ${org ? `AND org = ${org}` : ``}
            ORDER BY hist_id DESC 
            LIMIT ${n - 1}, 1)`;

    const records = await database.query(sql);
    let dependencies = [];

    // map records to promises
    return await Promise.all(records.map(record => 
        getDepWrapper(record.dep_name_version, dependencies)
    ));
}

通过简化您的代码,可以更容易地确定您在哪里出错。假设GETEdvRePress实际上解决了,你应该是好的。

你应该考虑停止使用<代码>新约定()/<代码>。这是一种反模式的坏习惯。您还可能从
async/await
中受益匪浅。我无法从外部判断是什么导致了inifite循环,但至少这两件事应该会大大简化您的代码,并使问题更容易被发现。还注意到您在数据库调用中混合了回调和承诺。绝对值得清理一下!如果有帮助的话,我写了这篇文章:什么是反模式?最好概括为“一些并不罕见的事情”,但“一个相当糟糕的做法”。你可以在谷歌上搜索“Promise constructor anti pattern”,以获取关于这一模式的大量信息。
async function retrieveDependency(projname, branch, n, org=undefined) {
    // combine both queries
    const sql = `
        SELECT * FROM branch_scan 
        WHERE fossa_scan_id = (
            SELECT (scanid) FROM foozie 
            WHERE 
                project = ${projname} 
                AND branch = ${branch} 
                ${org ? `AND org = ${org}` : ``}
            ORDER BY hist_id DESC 
            LIMIT ${n - 1}, 1)`;

    const records = await database.query(sql);
    let dependencies = [];

    // map records to promises
    return await Promise.all(records.map(record => 
        getDepWrapper(record.dep_name_version, dependencies)
    ));
}