не может вернуть данные из функции - PullRequest
0 голосов
/ 04 мая 2020

В этом nodejs, expressJs проекте на основе я не могу вернуть данные из одной функции

 router.get('/', async(req, res) => {
  const meta = getMeta();
  console.log('meta', meta) // this prints the string
  const reactComp = renderToString(<Index />);
  res.status(200).render('pages/index', { reactApp: reactComp, title: meta })
})

function getMeta(){
 console.log("I ran")
 let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
 db.query(sql, (err, rows) => {
    if(err) throw err;
    console.log(rows) // this is printing the data
});
// return rows // this is not working and gives an error
return 'Coming from getMeta'

}

Я просто хочу вернуть данные из функции getMeta в первую.

Спасибо за помощь.

Ответы [ 3 ]

1 голос
/ 04 мая 2020

Используйте обещание для mysql, вы не можете использовать return в функции обратного вызова.

Попробуйте это:


function getMeta(){
    return new Promise(resolve => {
      console.log("I ran")
      let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'
      db.query(sql, (err, rows) => {
        if(err) throw err;
        console.log(rows) // this is printing the data
        resolve(rows) //this will make the return
     });
});

0 голосов
/ 04 мая 2020

У вас есть несколько проблем там, во-первых, конец вашей функции, где вы хотите вернуть строки. Строки не определены, так как они находятся только в области обратного вызова sql.

Следующее, что, даже если ваша переменная строк была определена, в тот момент, когда вы вернетесь, sql не вернет данные тем не менее, вы должны вернуть некоторую пустую переменную.

Причина, по которой этот обратный вызов существует, заключается в том, чтобы иметь возможность ждать sql, чтобы вернуть данные, и как только sql имеет строки, чтобы использовать их внутри обратного вызова .

Самая базовая c реализация выглядела бы так:

 router.get('/', async(req, res) => {
   const sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'  
   db.query(sql, (err, rows) => {
     if(err) throw err;
     const reactComp = renderToString(<Index />);
     res.status(200).render('pages/index', { reactApp: reactComp, title: rows })
   });
})

Видите ли, мы ждем, пока данные поступят внутри обратного вызова и вернут оттуда наш ответ.

Теперь могут быть причудливые способы обернуть это в обещание или что-то в этом роде:

function getMeta() {
    const sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'  
   // wrapping the query in a promise
   return new Promise((resolve, reject) => {
    db.query(sql, (err, rows) => {
      if(err) reject(err);
      resolve(rows)
    });
  })
}

// now we can use the await keyword
router.get('/', async(req, res) => {
  const meta = await getMeta()
  console.log('meta', meta)
  const reactComp = renderToString(<Index />)
  res.status(200).render('pages/index', { reactApp: reactComp, title: meta })
})
0 голосов
/ 04 мая 2020

Если вы используете обещания, вы должны вернуться изнутри функции.

function getMeta () {

let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'

return db.query(sql, (err, rows) => { // <- Add return
  if (err) throw err;
  return rows //  <- Add return
});
}

Но также вы бы сделали ее асинхронной.

function getMeta() {

(async () => {
  let sql = 'SELECT `title`, `description`, `keyword` FROM `metas` WHERE `url`="-"'

  try {
    const result = await await db.query(sql)
    if (!result) throw Error

    return result

  } catch (err) {
    // handle error
  }

 })()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...