MySQL,节点,查询中的查询,如何从另一个查询中填充地图函数中的属性

时间:2019-04-29 13:10:33

标签: mysql node.js express

首先,如果任何人都可以编辑我的问题标题或问题以使其更有意义,请这样做。

我有一个节点/快速应用程序,使用mysql.js进行mysql查询。我有一个查询,查询一个问题表,然后对结果运行一个map函数。在该映射函数中,我需要查询另一个表,该表的答案与问题表中的每个记录相对应。我需要的值是该问题的答案数,即每个答案表中的记录数。我已经尝试了各种不同的示例,但是没有一种适合我的情况。是Node和Express的新功能,甚至是MySQL的新功能,因此很难选择要做什么。

我知道问题在于节点的异步特性。在查询完成之前,getAnswersCount()返回“计数”。下面是我的代码。需要一些有关如何实现这一目标的建议。

分配值123只是为了澄清跟踪结果。

app.get('/', (req, res) => {

db.query('SELECT * FROM questions LIMIT 0, 100',
  (error, results) => {
    if (error) throw error;

    questions = results.map(q => ({
      id: q.id,
      title: q.title,
      description: q.description,
      answers: getAnswersCount( q.id )
    }));

    res.send( questions );
  });

});

const getAnswersCount = ( id ) =>
{
  const tableName = 'answers_' + id;
  var count = 123;

  var sql = `CREATE TABLE IF NOT EXISTS ${tableName}(
                          id int primary key not null,
                          answer varchar(250) not null
                      )`;

  db.query( sql,
    (error, results) => {
      if (error) throw error;
      //console.log( 'answers table created!' );
  });

  sql = `SELECT COUNT(*) AS answersCount FROM ${tableName}`;

  db.query( sql,
    (error, results) => {
      if (error) throw error;

      //console.log( count ); // will=123
      count = results[0].answersCount;
      //console.log( count ); // will = results[0].answerCount
  });

  // I know this code runs before the query finishes, so what to do?
  //console.log( count ); //still 123 instead of results[0].answersCount

  return count;
}

编辑:尝试了迈克尔·普拉特(Michael Platt)在其答案中的各种版本都没有成功之后,我终于找到了使用Express回调和Promise的解决方案,然后将答案值添加到问题数组:

app.get( '/', (req, res, next ) => {

  db.query('SELECT * FROM questions LIMIT 0, 100',
    (error, results) => {
      if (error) throw error;

        questions = results.map(q => ({
        id: q.id,
        title: q.title,
        description: q.description,
      }));

      next();
    });

}, (req, res ) => {
  questions.map( currentElem => {

    getAnswersCount( currentElem.id ).then( rowData => {
      currentElem.answers = rowData[0].answersCount;

      if( currentElem.id == questions.length ) res.send( questions );
    });

  });
});

const getAnswersCount = ( id ) => {
  const tableName = 'answers_' + id;

  var sql = `CREATE TABLE IF NOT EXISTS ${tableName}(
                          id int primary key not null,
                          answer varchar(250) not null
                      )`;

  db.query( sql,
    (error, results) => {
      if (error) throw error;
      //console.log( 'answers table created!' );
  });

  sql = `SELECT COUNT(*) AS answersCount FROM ${tableName}`;

  return new Promise( ( resolve, reject ) => {
      db.query( sql, ( error, results ) => {
          if ( error ) return reject( err );
          resolve( results );
      });
  });
}

1 个答案:

答案 0 :(得分:0)

我不确定您要使用哪个数据库模块来连接并查询数据库,但是可以使方法async然后等待查询的响应,如下所示:

const getAnswersCount = async ( id ) =>
{
   const tableName = 'answers_' + id;
   var count = 123;

   var sql = `CREATE TABLE IF NOT EXISTS ${tableName}(
                      id int primary key not null,
                      answer varchar(250) not null
                  )`;

   var results = await db.query(sql);

   sql = `SELECT COUNT(*) AS answersCount FROM ${tableName}`;

   var count = db.query(sql)[0].answerCount;

   // I know this code runs before the query finishes, so what to do?
   //console.log( count ); //still 123 instead of results[0].answersCount

   return count;
}

app.get('/', async (req, res) => {
   db.query('SELECT * FROM questions LIMIT 0, 100',
      (error, results) => {
        if (error) throw error;
        questions = results.map(q => {
          const answerCount = await getAnswersCount( q.id )
          return {
             id: q.id,
             title: q.title,
             description: q.description,
             answers: answerCount
          }
        }));

    res.send( questions );
  });

});

我认为这将为您提供所需的内容并正确运行,但是可能需要进行一些调整。您可能还需要在实际路由本身上使用async函数,并等待对getAnswersCount的调用,但这应该就可以完成。