Express.js: пустой объект отправлен вместе с ответом - PullRequest
0 голосов
/ 15 октября 2019

У меня есть три подготовленных оператора SQL, которые я хочу выполнить. После выполнения оператора SQL результаты добавляются в объект ответа, а затем отправляются клиенту. В ответе отображается пустой объект, хотя он должен быть там. Возможно, я ошибаюсь, но думаю, что мой ответ не в том месте. Любые другие предложения приветствуются, так как я все еще новичок в Node.js.

    const s1 = 'small sql statement'

    const s2 = 'small sql statement'

    const s3 = 'small sql statement'

    var responseObject = {}

    const onError = err => {res.send({error: err}); console.error(err)}
    const updateResponse = results => {results.map((item) => {Object.assign(responseObject, item)})}
    const statements = [s1, s2, s3]

    router.get('/stats', (req,res,next) => {
        statements.map((statement) => {
            con.query(statement, (err,results) => {
                if (err) onError(err);
                 updateResponse(results);
            })
        })
        res.send({
            success: responseObject
        })
    })

    module.exports = router;

Ответы [ 2 ]

1 голос
/ 15 октября 2019

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

Вы можете использовать обещания для обработки этого:

const s1 = 'small sql statement'

const s2 = 'small sql statement'

const s3 = 'small sql statement'

const statements = [s1, s2, s3]

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

  // Generate array of promises
  const promises = statements.map(statement => {
    return new Promise((resolve, reject) => {

      con.query(statement, (err, results) => {
        if (err) reject(err);
        resolve(results);
      });

    });
  });

  // Wait for all promises to resolve
  Promise.all(promises)
    .then(results => {

      // Merge results into single object
      const responseObject = results
        .flat()
        .reduce((acc, cur) => Object.assign(acc, cur), {});

      res.send({ success: responseObject });
    })
    .catch(err => {
      res.send({ error: err });
      console.error(err);
    });

});

module.exports = router;

Если ваша версия Node не поддерживает .flat() тогда вы можете изменить это:

const responseObject = [].concat.apply([], results)
  .reduce((acc, cur) => Object.assign(acc, cur), {});
0 голосов
/ 15 октября 2019

Выполнение запроса к базе данных является асинхронной задачей. Вы отправляете ответ еще до того, как запросы завершены, выполняя которые, как вы заявили, пустые. Вы можете использовать async / await или обещание для асинхронного выполнения и ожидания данных, а затем добавить данные в responseObject.

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