Перемещение кода в экспортируемую функцию приводит к TypeError: преобразование круговой структуры в JSON - PullRequest
2 голосов
/ 22 января 2020

Я использую пакеты express и mysql, чтобы просто протестировать запросы.

У меня был этот код:

connection.connect();

connection.query('SELECT 1 + 1 AS solution', (error, results) => {
  if (error) {
    connection.end();
    console.log('error');
    throw error;
  }
  connection.end();
  console.log(results);
  return results;
});

И он работает просто отлично. Но когда я перемещаю его в другой файл и пытаюсь экспортировать его так:

query.js

const connection = require('../config/connection');

connection.connect();

module.exports = async (query) => connection.query(query, (error, results) => {
  console.log(query);
  if (error) {
    // connection.end();
    console.log('error');
    throw error;
  }
  // connection.end();
  console.log(results);
  return results;
});

app.js

try {
  const queryResult = await query('SELECT 1 + 1 AS solution');
  console.log(queryResult, 2);
  res.send(queryResult);
} catch (err) {
  console.log(err);
}

Я получаю это ошибка:

TypeError: Converting circular structure to JSON
at JSON.stringify (<anonymous>)
at stringify (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:1119:12)
at ServerResponse.json (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:260:14)
at ServerResponse.send (C:\Users\aironsid\Documents\tatooify\server\node_modules\express\lib\response.js:158:21)
at app.get (C:\Users\aironsid\Documents\tatooify\server\app.js:44:9)
at process._tickCallback (internal/process/next_tick.js:68:7)

Также в консольных логах я получаю большой объект, за которым следует номер 2, затем я получаю errthe `` или, затем я получаю значение запроса, а затем результат. Вот так:

Big object 2

error

SELECT 1 + 1 AS solution

[ RowDataPacket { solution: 2 } ]

Итак, это говорит мне о том, что мой код работает в asyn c. Удаление async / await из обоих файлов ничего не меняет. Итак, мой код сначала запускает код app.js, затем код query.js, что занимает некоторое время. Но почему? И как я могу заставить это ждать? connection.query() не не вернуть обещание.

1 Ответ

1 голос
/ 22 января 2020

Проблема в том, что ваша async функция не ожидает окончания запроса до 1025 *.

. Она должна возвращать обещание, которое разрешается после завершения запроса, но вместо этого возвращает обещание, которое немедленно разрешается в возвращаемое значение. функции connection.query().

Вы должны изменить это на:

module.exports = (query) => {

    return new Promise(resolve => 
        connection.query(query, (error, results) => {
          console.log(query);
          if (error) {
            // connection.end();
            console.log('error');
            throw error;
          }
          // connection.end();
          console.log(results);
          resolve(results);
        })
    );

}

С опущенными закомментированными строками и более коротким синтаксисом:

module.exports = (query) => new Promise((resolve, reject) => 
  connection.query(query, (error, results) => {
    if (error) return reject(error);

    resolve(results);
  })
);

И еще короче:

module.exports = (query) => 
  new Promise((resolve, reject) => 
    connection.query(query, (error, results) => 
      error ? reject(error) : resolve(results)
  )
);

Чтобы уточнить : ваше ключевое слово async не имело никакого эффекта, потому что оно позволяет вам использовать await в своей функции и переносить все, что вы возвращаете в обещание.

Вы не использовали await s и немедленно вернули результат с помощью лямбда-функции.

Обратите внимание, что ваш оператор возврата, возвращаемый из обратного вызова, передается в функцию connection.query, а не из главной функции.

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